authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-06-20 14:02:04-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-06-20 14:02:09-04:00
log96cdd51c14337b012910a36ba93121a371509cfd
tree9b75389283a2446a2fbc6450e5755faae6410851
parent52ec121469d7bf10116fb22c122cbce8ceddd028

Type: delete legacy allocation functions


13 files changed, 976 insertions(+), 1080 deletions(-)

src/InternPool.zig+3-2
...@@ -2301,8 +2301,9 @@ pub const Alignment = enum(u6) {...@@ -2301,8 +2301,9 @@ pub const Alignment = enum(u6) {
2301 return fromByteUnits(n);2301 return fromByteUnits(n);
2302 }2302 }
23032303
2304 pub fn min(a: Alignment, b: Alignment) Alignment {2304 pub fn order(lhs: Alignment, rhs: Alignment) std.math.Order {
2305 return @enumFromInt(Alignment, @min(@intFromEnum(a), @intFromEnum(b)));2305 assert(lhs != .none and rhs != .none);
2306 return std.math.order(@intFromEnum(lhs), @intFromEnum(rhs));
2306 }2307 }
2307};2308};
23082309
src/Module.zig+25-44
...@@ -33,6 +33,7 @@ const Liveness = @import("Liveness.zig");...@@ -33,6 +33,7 @@ const Liveness = @import("Liveness.zig");
33const isUpDir = @import("introspect.zig").isUpDir;33const isUpDir = @import("introspect.zig").isUpDir;
34const clang = @import("clang.zig");34const clang = @import("clang.zig");
35const InternPool = @import("InternPool.zig");35const InternPool = @import("InternPool.zig");
36const Alignment = InternPool.Alignment;
3637
37comptime {38comptime {
38 @setEvalBranchQuota(4000);39 @setEvalBranchQuota(4000);
...@@ -241,7 +242,7 @@ pub const MonomorphedFuncsAdaptedContext = struct {...@@ -241,7 +242,7 @@ pub const MonomorphedFuncsAdaptedContext = struct {
241};242};
242243
243pub const SetAlignStack = struct {244pub const SetAlignStack = struct {
244 alignment: u32,245 alignment: Alignment,
245 /// TODO: This needs to store a non-lazy source location for the case of an inline function246 /// TODO: This needs to store a non-lazy source location for the case of an inline function
246 /// which does `@setAlignStack` (applying it to the caller).247 /// which does `@setAlignStack` (applying it to the caller).
247 src: LazySrcLoc,248 src: LazySrcLoc,
...@@ -432,7 +433,7 @@ pub const Decl = struct {...@@ -432,7 +433,7 @@ pub const Decl = struct {
432 /// Populated when `has_tv`.433 /// Populated when `has_tv`.
433 @"linksection": InternPool.OptionalNullTerminatedString,434 @"linksection": InternPool.OptionalNullTerminatedString,
434 /// Populated when `has_tv`.435 /// Populated when `has_tv`.
435 @"align": u32,436 alignment: Alignment,
436 /// Populated when `has_tv`.437 /// Populated when `has_tv`.
437 @"addrspace": std.builtin.AddressSpace,438 @"addrspace": std.builtin.AddressSpace,
438 /// The direct parent namespace of the Decl.439 /// The direct parent namespace of the Decl.
...@@ -863,13 +864,7 @@ pub const Decl = struct {...@@ -863,13 +864,7 @@ pub const Decl = struct {
863864
864 pub fn getAlignment(decl: Decl, mod: *Module) u32 {865 pub fn getAlignment(decl: Decl, mod: *Module) u32 {
865 assert(decl.has_tv);866 assert(decl.has_tv);
866 if (decl.@"align" != 0) {867 return @intCast(u32, decl.alignment.toByteUnitsOptional() orelse decl.ty.abiAlignment(mod));
867 // Explicit alignment.
868 return decl.@"align";
869 } else {
870 // Natural alignment.
871 return decl.ty.abiAlignment(mod);
872 }
873 }868 }
874869
875 pub fn intern(decl: *Decl, mod: *Module) Allocator.Error!void {870 pub fn intern(decl: *Decl, mod: *Module) Allocator.Error!void {
...@@ -955,7 +950,7 @@ pub const Struct = struct {...@@ -955,7 +950,7 @@ pub const Struct = struct {
955 /// Uses `none` to indicate no default.950 /// Uses `none` to indicate no default.
956 default_val: InternPool.Index,951 default_val: InternPool.Index,
957 /// Zero means to use the ABI alignment of the type.952 /// Zero means to use the ABI alignment of the type.
958 abi_align: u32,953 abi_align: Alignment,
959 /// undefined until `status` is `have_layout`.954 /// undefined until `status` is `have_layout`.
960 offset: u32,955 offset: u32,
961 /// If true then `default_val` is the comptime field value.956 /// If true then `default_val` is the comptime field value.
...@@ -967,9 +962,9 @@ pub const Struct = struct {...@@ -967,9 +962,9 @@ pub const Struct = struct {
967 mod: *Module,962 mod: *Module,
968 layout: std.builtin.Type.ContainerLayout,963 layout: std.builtin.Type.ContainerLayout,
969 ) u32 {964 ) u32 {
970 if (field.abi_align != 0) {965 if (field.abi_align.toByteUnitsOptional()) |abi_align| {
971 assert(layout != .Packed);966 assert(layout != .Packed);
972 return field.abi_align;967 return @intCast(u32, abi_align);
973 }968 }
974969
975 const target = mod.getTarget();970 const target = mod.getTarget();
...@@ -1150,17 +1145,13 @@ pub const Union = struct {...@@ -1150,17 +1145,13 @@ pub const Union = struct {
1150 /// undefined until `status` is `have_field_types` or `have_layout`.1145 /// undefined until `status` is `have_field_types` or `have_layout`.
1151 ty: Type,1146 ty: Type,
1152 /// 0 means the ABI alignment of the type.1147 /// 0 means the ABI alignment of the type.
1153 abi_align: u32,1148 abi_align: Alignment,
11541149
1155 /// Returns the field alignment, assuming the union is not packed.1150 /// Returns the field alignment, assuming the union is not packed.
1156 /// Keep implementation in sync with `Sema.unionFieldAlignment`.1151 /// Keep implementation in sync with `Sema.unionFieldAlignment`.
1157 /// Prefer to call that function instead of this one during Sema.1152 /// Prefer to call that function instead of this one during Sema.
1158 pub fn normalAlignment(field: Field, mod: *Module) u32 {1153 pub fn normalAlignment(field: Field, mod: *Module) u32 {
1159 if (field.abi_align == 0) {1154 return @intCast(u32, field.abi_align.toByteUnitsOptional() orelse field.ty.abiAlignment(mod));
1160 return field.ty.abiAlignment(mod);
1161 } else {
1162 return field.abi_align;
1163 }
1164 }1155 }
1165 };1156 };
11661157
...@@ -1272,20 +1263,14 @@ pub const Union = struct {...@@ -1272,20 +1263,14 @@ pub const Union = struct {
1272 for (fields, 0..) |field, i| {1263 for (fields, 0..) |field, i| {
1273 if (!field.ty.hasRuntimeBitsIgnoreComptime(mod)) continue;1264 if (!field.ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
12741265
1275 const field_align = a: {1266 const field_align = field.abi_align.toByteUnitsOptional() orelse field.ty.abiAlignment(mod);
1276 if (field.abi_align == 0) {
1277 break :a field.ty.abiAlignment(mod);
1278 } else {
1279 break :a field.abi_align;
1280 }
1281 };
1282 const field_size = field.ty.abiSize(mod);1267 const field_size = field.ty.abiSize(mod);
1283 if (field_size > payload_size) {1268 if (field_size > payload_size) {
1284 payload_size = field_size;1269 payload_size = field_size;
1285 biggest_field = @intCast(u32, i);1270 biggest_field = @intCast(u32, i);
1286 }1271 }
1287 if (field_align > payload_align) {1272 if (field_align > payload_align) {
1288 payload_align = field_align;1273 payload_align = @intCast(u32, field_align);
1289 most_aligned_field = @intCast(u32, i);1274 most_aligned_field = @intCast(u32, i);
1290 most_aligned_field_size = field_size;1275 most_aligned_field_size = field_size;
1291 }1276 }
...@@ -4394,7 +4379,7 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {...@@ -4394,7 +4379,7 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {
4394 new_decl.has_linksection_or_addrspace = false;4379 new_decl.has_linksection_or_addrspace = false;
4395 new_decl.ty = Type.type;4380 new_decl.ty = Type.type;
4396 new_decl.val = struct_ty.toValue();4381 new_decl.val = struct_ty.toValue();
4397 new_decl.@"align" = 0;4382 new_decl.alignment = .none;
4398 new_decl.@"linksection" = .none;4383 new_decl.@"linksection" = .none;
4399 new_decl.has_tv = true;4384 new_decl.has_tv = true;
4400 new_decl.owns_tv = true;4385 new_decl.owns_tv = true;
...@@ -4584,7 +4569,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {...@@ -4584,7 +4569,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
45844569
4585 decl.ty = InternPool.Index.type_type.toType();4570 decl.ty = InternPool.Index.type_type.toType();
4586 decl.val = ty.toValue();4571 decl.val = ty.toValue();
4587 decl.@"align" = 0;4572 decl.alignment = .none;
4588 decl.@"linksection" = .none;4573 decl.@"linksection" = .none;
4589 decl.has_tv = true;4574 decl.has_tv = true;
4590 decl.owns_tv = false;4575 decl.owns_tv = false;
...@@ -4665,9 +4650,9 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {...@@ -4665,9 +4650,9 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
46654650
4666 decl.ty = decl_tv.ty;4651 decl.ty = decl_tv.ty;
4667 decl.val = (try decl_tv.val.intern(decl_tv.ty, mod)).toValue();4652 decl.val = (try decl_tv.val.intern(decl_tv.ty, mod)).toValue();
4668 decl.@"align" = blk: {4653 decl.alignment = blk: {
4669 const align_ref = decl.zirAlignRef(mod);4654 const align_ref = decl.zirAlignRef(mod);
4670 if (align_ref == .none) break :blk 0;4655 if (align_ref == .none) break :blk .none;
4671 break :blk try sema.resolveAlign(&block_scope, align_src, align_ref);4656 break :blk try sema.resolveAlign(&block_scope, align_src, align_ref);
4672 };4657 };
4673 decl.@"linksection" = blk: {4658 decl.@"linksection" = blk: {
...@@ -5758,7 +5743,7 @@ pub fn allocateNewDecl(...@@ -5758,7 +5743,7 @@ pub fn allocateNewDecl(
5758 .owns_tv = false,5743 .owns_tv = false,
5759 .ty = undefined,5744 .ty = undefined,
5760 .val = undefined,5745 .val = undefined,
5761 .@"align" = undefined,5746 .alignment = undefined,
5762 .@"linksection" = .none,5747 .@"linksection" = .none,
5763 .@"addrspace" = .generic,5748 .@"addrspace" = .generic,
5764 .analysis = .unreferenced,5749 .analysis = .unreferenced,
...@@ -5830,7 +5815,7 @@ pub fn initNewAnonDecl(...@@ -5830,7 +5815,7 @@ pub fn initNewAnonDecl(
5830 new_decl.src_line = src_line;5815 new_decl.src_line = src_line;
5831 new_decl.ty = typed_value.ty;5816 new_decl.ty = typed_value.ty;
5832 new_decl.val = typed_value.val;5817 new_decl.val = typed_value.val;
5833 new_decl.@"align" = 0;5818 new_decl.alignment = .none;
5834 new_decl.@"linksection" = .none;5819 new_decl.@"linksection" = .none;
5835 new_decl.has_tv = true;5820 new_decl.has_tv = true;
5836 new_decl.analysis = .complete;5821 new_decl.analysis = .complete;
...@@ -6773,13 +6758,9 @@ pub fn manyConstPtrType(mod: *Module, child_type: Type) Allocator.Error!Type {...@@ -6773,13 +6758,9 @@ pub fn manyConstPtrType(mod: *Module, child_type: Type) Allocator.Error!Type {
6773}6758}
67746759
6775pub fn adjustPtrTypeChild(mod: *Module, ptr_ty: Type, new_child: Type) Allocator.Error!Type {6760pub fn adjustPtrTypeChild(mod: *Module, ptr_ty: Type, new_child: Type) Allocator.Error!Type {
6776 const info = Type.ptrInfoIp(&mod.intern_pool, ptr_ty.toIntern());6761 var info = ptr_ty.ptrInfo(mod);
6777 return mod.ptrType(.{6762 info.child = new_child.toIntern();
6778 .child = new_child.toIntern(),6763 return mod.ptrType(info);
6779 .sentinel = info.sentinel,
6780 .flags = info.flags,
6781 .packed_offset = info.packed_offset,
6782 });
6783}6764}
67846765
6785pub fn funcType(mod: *Module, info: InternPool.Key.FuncType) Allocator.Error!Type {6766pub fn funcType(mod: *Module, info: InternPool.Key.FuncType) Allocator.Error!Type {
...@@ -7018,7 +6999,7 @@ pub fn atomicPtrAlignment(...@@ -7018,7 +6999,7 @@ pub fn atomicPtrAlignment(
7018 mod: *Module,6999 mod: *Module,
7019 ty: Type,7000 ty: Type,
7020 diags: *AtomicPtrAlignmentDiagnostics,7001 diags: *AtomicPtrAlignmentDiagnostics,
7021) AtomicPtrAlignmentError!u32 {7002) AtomicPtrAlignmentError!Alignment {
7022 const target = mod.getTarget();7003 const target = mod.getTarget();
7023 const max_atomic_bits: u16 = switch (target.cpu.arch) {7004 const max_atomic_bits: u16 = switch (target.cpu.arch) {
7024 .avr,7005 .avr,
...@@ -7104,11 +7085,11 @@ pub fn atomicPtrAlignment(...@@ -7104,11 +7085,11 @@ pub fn atomicPtrAlignment(
7104 };7085 };
7105 return error.FloatTooBig;7086 return error.FloatTooBig;
7106 }7087 }
7107 return 0;7088 return .none;
7108 },7089 },
7109 .Bool => return 0,7090 .Bool => return .none,
7110 else => {7091 else => {
7111 if (ty.isPtrAtRuntime(mod)) return 0;7092 if (ty.isPtrAtRuntime(mod)) return .none;
7112 return error.BadType;7093 return error.BadType;
7113 },7094 },
7114 };7095 };
...@@ -7122,7 +7103,7 @@ pub fn atomicPtrAlignment(...@@ -7122,7 +7103,7 @@ pub fn atomicPtrAlignment(
7122 return error.IntTooBig;7103 return error.IntTooBig;
7123 }7104 }
71247105
7125 return 0;7106 return .none;
7126}7107}
71277108
7128pub fn opaqueSrcLoc(mod: *Module, opaque_type: InternPool.Key.OpaqueType) SrcLoc {7109pub fn opaqueSrcLoc(mod: *Module, opaque_type: InternPool.Key.OpaqueType) SrcLoc {
src/Sema.zig+725-663
...@@ -126,6 +126,7 @@ const crash_report = @import("crash_report.zig");...@@ -126,6 +126,7 @@ const crash_report = @import("crash_report.zig");
126const build_options = @import("build_options");126const build_options = @import("build_options");
127const Compilation = @import("Compilation.zig");127const Compilation = @import("Compilation.zig");
128const InternPool = @import("InternPool.zig");128const InternPool = @import("InternPool.zig");
129const Alignment = InternPool.Alignment;
129130
130pub const default_branch_quota = 1000;131pub const default_branch_quota = 1000;
131pub const default_reference_trace_len = 2;132pub const default_reference_trace_len = 2;
...@@ -708,7 +709,7 @@ pub const Block = struct {...@@ -708,7 +709,7 @@ pub const Block = struct {
708 }709 }
709710
710 /// `alignment` value of 0 means to use ABI alignment.711 /// `alignment` value of 0 means to use ABI alignment.
711 pub fn finish(wad: *WipAnonDecl, ty: Type, val: Value, alignment: u64) !Decl.Index {712 pub fn finish(wad: *WipAnonDecl, ty: Type, val: Value, alignment: Alignment) !Decl.Index {
712 const sema = wad.block.sema;713 const sema = wad.block.sema;
713 // Do this ahead of time because `createAnonymousDecl` depends on calling714 // Do this ahead of time because `createAnonymousDecl` depends on calling
714 // `type.hasRuntimeBits()`.715 // `type.hasRuntimeBits()`.
...@@ -718,8 +719,7 @@ pub const Block = struct {...@@ -718,8 +719,7 @@ pub const Block = struct {
718 .val = val,719 .val = val,
719 });720 });
720 const new_decl = sema.mod.declPtr(new_decl_index);721 const new_decl = sema.mod.declPtr(new_decl_index);
721 // TODO: migrate Decl alignment to use `InternPool.Alignment`722 new_decl.alignment = alignment;
722 new_decl.@"align" = @intCast(u32, alignment);
723 errdefer sema.mod.abortAnonDecl(new_decl_index);723 errdefer sema.mod.abortAnonDecl(new_decl_index);
724 wad.finished = true;724 wad.finished = true;
725 try sema.mod.finalizeAnonDecl(new_decl_index);725 try sema.mod.finalizeAnonDecl(new_decl_index);
...@@ -1847,7 +1847,10 @@ pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize)...@@ -1847,7 +1847,10 @@ pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize)
18471847
1848 // var addrs: [err_return_trace_addr_count]usize = undefined;1848 // var addrs: [err_return_trace_addr_count]usize = undefined;
1849 const err_return_trace_addr_count = 32;1849 const err_return_trace_addr_count = 32;
1850 const addr_arr_ty = try Type.array(sema.arena, err_return_trace_addr_count, null, Type.usize, mod);1850 const addr_arr_ty = try mod.arrayType(.{
1851 .len = err_return_trace_addr_count,
1852 .child = .usize_type,
1853 });
1851 const addrs_ptr = try err_trace_block.addTy(.alloc, try mod.singleMutPtrType(addr_arr_ty));1854 const addrs_ptr = try err_trace_block.addTy(.alloc, try mod.singleMutPtrType(addr_arr_ty));
18521855
1853 // var st: StackTrace = undefined;1856 // var st: StackTrace = undefined;
...@@ -2192,9 +2195,9 @@ fn typeSupportsFieldAccess(mod: *const Module, ty: Type, field_name: InternPool....@@ -2192,9 +2195,9 @@ fn typeSupportsFieldAccess(mod: *const Module, ty: Type, field_name: InternPool.
2192 .Array => return ip.stringEqlSlice(field_name, "len"),2195 .Array => return ip.stringEqlSlice(field_name, "len"),
2193 .Pointer => {2196 .Pointer => {
2194 const ptr_info = ty.ptrInfo(mod);2197 const ptr_info = ty.ptrInfo(mod);
2195 if (ptr_info.size == .Slice) {2198 if (ptr_info.flags.size == .Slice) {
2196 return ip.stringEqlSlice(field_name, "ptr") or ip.stringEqlSlice(field_name, "len");2199 return ip.stringEqlSlice(field_name, "ptr") or ip.stringEqlSlice(field_name, "len");
2197 } else if (ptr_info.pointee_type.zigTypeTag(mod) == .Array) {2200 } else if (ptr_info.child.toType().zigTypeTag(mod) == .Array) {
2198 return ip.stringEqlSlice(field_name, "len");2201 return ip.stringEqlSlice(field_name, "len");
2199 } else return false;2202 } else return false;
2200 },2203 },
...@@ -2408,11 +2411,11 @@ fn analyzeAsAlign(...@@ -2408,11 +2411,11 @@ fn analyzeAsAlign(
2408 block: *Block,2411 block: *Block,
2409 src: LazySrcLoc,2412 src: LazySrcLoc,
2410 air_ref: Air.Inst.Ref,2413 air_ref: Air.Inst.Ref,
2411) !u32 {2414) !Alignment {
2412 const alignment_big = try sema.analyzeAsInt(block, src, air_ref, align_ty, "alignment must be comptime-known");2415 const alignment_big = try sema.analyzeAsInt(block, src, air_ref, align_ty, "alignment must be comptime-known");
2413 const alignment = @intCast(u32, alignment_big); // We coerce to u16 in the prev line.2416 const alignment = @intCast(u32, alignment_big); // We coerce to u29 in the prev line.
2414 try sema.validateAlign(block, src, alignment);2417 try sema.validateAlign(block, src, alignment);
2415 return alignment;2418 return Alignment.fromNonzeroByteUnits(alignment);
2416}2419}
24172420
2418fn validateAlign(2421fn validateAlign(
...@@ -2434,7 +2437,7 @@ pub fn resolveAlign(...@@ -2434,7 +2437,7 @@ pub fn resolveAlign(
2434 block: *Block,2437 block: *Block,
2435 src: LazySrcLoc,2438 src: LazySrcLoc,
2436 zir_ref: Zir.Inst.Ref,2439 zir_ref: Zir.Inst.Ref,
2437) !u32 {2440) !Alignment {
2438 const air_ref = try sema.resolveInst(zir_ref);2441 const air_ref = try sema.resolveInst(zir_ref);
2439 return sema.analyzeAsAlign(block, src, air_ref);2442 return sema.analyzeAsAlign(block, src, air_ref);
2440}2443}
...@@ -2550,7 +2553,7 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE...@@ -2550,7 +2553,7 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
2550 const decl_index = try anon_decl.finish(2553 const decl_index = try anon_decl.finish(
2551 pointee_ty,2554 pointee_ty,
2552 (try mod.intern(.{ .undef = pointee_ty.toIntern() })).toValue(),2555 (try mod.intern(.{ .undef = pointee_ty.toIntern() })).toValue(),
2553 alignment.toByteUnits(0),2556 alignment,
2554 );2557 );
2555 sema.air_instructions.items(.data)[ptr_inst].inferred_alloc_comptime.decl_index = decl_index;2558 sema.air_instructions.items(.data)[ptr_inst].inferred_alloc_comptime.decl_index = decl_index;
2556 if (alignment != .none) {2559 if (alignment != .none) {
...@@ -2626,9 +2629,9 @@ fn coerceResultPtr(...@@ -2626,9 +2629,9 @@ fn coerceResultPtr(
2626 }2629 }
2627 }2630 }
26282631
2629 const ptr_ty = try Type.ptr(sema.arena, sema.mod, .{2632 const ptr_ty = try mod.ptrType(.{
2630 .pointee_type = pointee_ty,2633 .child = pointee_ty.toIntern(),
2631 .@"addrspace" = addr_space,2634 .flags = .{ .address_space = addr_space },
2632 });2635 });
26332636
2634 var new_ptr = ptr;2637 var new_ptr = ptr;
...@@ -2656,9 +2659,9 @@ fn coerceResultPtr(...@@ -2656,9 +2659,9 @@ fn coerceResultPtr(
2656 // Array coerced to Vector where element size is not equal but coercible.2659 // Array coerced to Vector where element size is not equal but coercible.
2657 .aggregate_init => {2660 .aggregate_init => {
2658 const ty_pl = air_datas[trash_inst].ty_pl;2661 const ty_pl = air_datas[trash_inst].ty_pl;
2659 const ptr_operand_ty = try Type.ptr(sema.arena, sema.mod, .{2662 const ptr_operand_ty = try mod.ptrType(.{
2660 .pointee_type = try sema.analyzeAsType(block, src, ty_pl.ty),2663 .child = (try sema.analyzeAsType(block, src, ty_pl.ty)).toIntern(),
2661 .@"addrspace" = addr_space,2664 .flags = .{ .address_space = addr_space },
2662 });2665 });
26632666
2664 if (try sema.resolveDefinedValue(block, src, new_ptr)) |ptr_val| {2667 if (try sema.resolveDefinedValue(block, src, new_ptr)) |ptr_val| {
...@@ -2670,9 +2673,9 @@ fn coerceResultPtr(...@@ -2670,9 +2673,9 @@ fn coerceResultPtr(
2670 .bitcast => {2673 .bitcast => {
2671 const ty_op = air_datas[trash_inst].ty_op;2674 const ty_op = air_datas[trash_inst].ty_op;
2672 const operand_ty = sema.typeOf(ty_op.operand);2675 const operand_ty = sema.typeOf(ty_op.operand);
2673 const ptr_operand_ty = try Type.ptr(sema.arena, sema.mod, .{2676 const ptr_operand_ty = try mod.ptrType(.{
2674 .pointee_type = operand_ty,2677 .child = operand_ty.toIntern(),
2675 .@"addrspace" = addr_space,2678 .flags = .{ .address_space = addr_space },
2676 });2679 });
2677 if (try sema.resolveDefinedValue(block, src, new_ptr)) |ptr_val| {2680 if (try sema.resolveDefinedValue(block, src, new_ptr)) |ptr_val| {
2678 new_ptr = try sema.addConstant(ptr_operand_ty, try mod.getCoerced(ptr_val, ptr_operand_ty));2681 new_ptr = try sema.addConstant(ptr_operand_ty, try mod.getCoerced(ptr_val, ptr_operand_ty));
...@@ -3382,13 +3385,13 @@ fn zirRetPtr(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {...@@ -3382,13 +3385,13 @@ fn zirRetPtr(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {
33823385
3383 if (block.is_comptime or try sema.typeRequiresComptime(sema.fn_ret_ty)) {3386 if (block.is_comptime or try sema.typeRequiresComptime(sema.fn_ret_ty)) {
3384 const fn_ret_ty = try sema.resolveTypeFields(sema.fn_ret_ty);3387 const fn_ret_ty = try sema.resolveTypeFields(sema.fn_ret_ty);
3385 return sema.analyzeComptimeAlloc(block, fn_ret_ty, 0);3388 return sema.analyzeComptimeAlloc(block, fn_ret_ty, .none);
3386 }3389 }
33873390
3388 const target = sema.mod.getTarget();3391 const target = sema.mod.getTarget();
3389 const ptr_type = try Type.ptr(sema.arena, sema.mod, .{3392 const ptr_type = try sema.mod.ptrType(.{
3390 .pointee_type = sema.fn_ret_ty,3393 .child = sema.fn_ret_ty.toIntern(),
3391 .@"addrspace" = target_util.defaultAddressSpace(target, .local),3394 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
3392 });3395 });
33933396
3394 if (block.inlining != null) {3397 if (block.inlining != null) {
...@@ -3560,12 +3563,12 @@ fn zirAllocExtended(...@@ -3560,12 +3563,12 @@ fn zirAllocExtended(
3560 break :blk try sema.resolveType(block, ty_src, type_ref);3563 break :blk try sema.resolveType(block, ty_src, type_ref);
3561 } else undefined;3564 } else undefined;
35623565
3563 const alignment: u32 = if (small.has_align) blk: {3566 const alignment = if (small.has_align) blk: {
3564 const align_ref = @enumFromInt(Zir.Inst.Ref, sema.code.extra[extra_index]);3567 const align_ref = @enumFromInt(Zir.Inst.Ref, sema.code.extra[extra_index]);
3565 extra_index += 1;3568 extra_index += 1;
3566 const alignment = try sema.resolveAlign(block, align_src, align_ref);3569 const alignment = try sema.resolveAlign(block, align_src, align_ref);
3567 break :blk alignment;3570 break :blk alignment;
3568 } else 0;3571 } else .none;
35693572
3570 if (block.is_comptime or small.is_comptime) {3573 if (block.is_comptime or small.is_comptime) {
3571 if (small.has_type) {3574 if (small.has_type) {
...@@ -3575,7 +3578,7 @@ fn zirAllocExtended(...@@ -3575,7 +3578,7 @@ fn zirAllocExtended(
3575 .tag = .inferred_alloc_comptime,3578 .tag = .inferred_alloc_comptime,
3576 .data = .{ .inferred_alloc_comptime = .{3579 .data = .{ .inferred_alloc_comptime = .{
3577 .decl_index = undefined,3580 .decl_index = undefined,
3578 .alignment = InternPool.Alignment.fromByteUnits(alignment),3581 .alignment = alignment,
3579 .is_const = small.is_const,3582 .is_const = small.is_const,
3580 } },3583 } },
3581 });3584 });
...@@ -3589,10 +3592,12 @@ fn zirAllocExtended(...@@ -3589,10 +3592,12 @@ fn zirAllocExtended(
3589 }3592 }
3590 const target = sema.mod.getTarget();3593 const target = sema.mod.getTarget();
3591 try sema.resolveTypeLayout(var_ty);3594 try sema.resolveTypeLayout(var_ty);
3592 const ptr_type = try Type.ptr(sema.arena, sema.mod, .{3595 const ptr_type = try sema.mod.ptrType(.{
3593 .pointee_type = var_ty,3596 .child = var_ty.toIntern(),
3594 .@"align" = alignment,3597 .flags = .{
3595 .@"addrspace" = target_util.defaultAddressSpace(target, .local),3598 .alignment = alignment,
3599 .address_space = target_util.defaultAddressSpace(target, .local),
3600 },
3596 });3601 });
3597 return block.addTy(.alloc, ptr_type);3602 return block.addTy(.alloc, ptr_type);
3598 }3603 }
...@@ -3600,7 +3605,7 @@ fn zirAllocExtended(...@@ -3600,7 +3605,7 @@ fn zirAllocExtended(
3600 const result_index = try block.addInstAsIndex(.{3605 const result_index = try block.addInstAsIndex(.{
3601 .tag = .inferred_alloc,3606 .tag = .inferred_alloc,
3602 .data = .{ .inferred_alloc = .{3607 .data = .{ .inferred_alloc = .{
3603 .alignment = InternPool.Alignment.fromByteUnits(alignment),3608 .alignment = alignment,
3604 .is_const = small.is_const,3609 .is_const = small.is_const,
3605 } },3610 } },
3606 });3611 });
...@@ -3615,7 +3620,7 @@ fn zirAllocComptime(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr...@@ -3615,7 +3620,7 @@ fn zirAllocComptime(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
3615 const inst_data = sema.code.instructions.items(.data)[inst].un_node;3620 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
3616 const ty_src: LazySrcLoc = .{ .node_offset_var_decl_ty = inst_data.src_node };3621 const ty_src: LazySrcLoc = .{ .node_offset_var_decl_ty = inst_data.src_node };
3617 const var_ty = try sema.resolveType(block, ty_src, inst_data.operand);3622 const var_ty = try sema.resolveType(block, ty_src, inst_data.operand);
3618 return sema.analyzeComptimeAlloc(block, var_ty, 0);3623 return sema.analyzeComptimeAlloc(block, var_ty, .none);
3619}3624}
36203625
3621fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {3626fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
...@@ -3625,7 +3630,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -3625,7 +3630,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
3625 const alloc_ty = sema.typeOf(alloc);3630 const alloc_ty = sema.typeOf(alloc);
36263631
3627 var ptr_info = alloc_ty.ptrInfo(mod);3632 var ptr_info = alloc_ty.ptrInfo(mod);
3628 const elem_ty = ptr_info.pointee_type;3633 const elem_ty = ptr_info.child.toType();
36293634
3630 // Detect if all stores to an `.alloc` were comptime-known.3635 // Detect if all stores to an `.alloc` were comptime-known.
3631 ct: {3636 ct: {
...@@ -3669,11 +3674,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -3669,11 +3674,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
36693674
3670 var anon_decl = try block.startAnonDecl();3675 var anon_decl = try block.startAnonDecl();
3671 defer anon_decl.deinit();3676 defer anon_decl.deinit();
3672 return sema.analyzeDeclRef(try anon_decl.finish(3677 return sema.analyzeDeclRef(try anon_decl.finish(elem_ty, store_val, ptr_info.flags.alignment));
3673 elem_ty,
3674 store_val,
3675 ptr_info.@"align",
3676 ));
3677 }3678 }
36783679
3679 return sema.makePtrConst(block, alloc);3680 return sema.makePtrConst(block, alloc);
...@@ -3684,8 +3685,8 @@ fn makePtrConst(sema: *Sema, block: *Block, alloc: Air.Inst.Ref) CompileError!Ai...@@ -3684,8 +3685,8 @@ fn makePtrConst(sema: *Sema, block: *Block, alloc: Air.Inst.Ref) CompileError!Ai
3684 const alloc_ty = sema.typeOf(alloc);3685 const alloc_ty = sema.typeOf(alloc);
36853686
3686 var ptr_info = alloc_ty.ptrInfo(mod);3687 var ptr_info = alloc_ty.ptrInfo(mod);
3687 ptr_info.mutable = false;3688 ptr_info.flags.is_const = true;
3688 const const_ptr_ty = try Type.ptr(sema.arena, sema.mod, ptr_info);3689 const const_ptr_ty = try mod.ptrType(ptr_info);
36893690
3690 // Detect if a comptime value simply needs to have its type changed.3691 // Detect if a comptime value simply needs to have its type changed.
3691 if (try sema.resolveMaybeUndefVal(alloc)) |val| {3692 if (try sema.resolveMaybeUndefVal(alloc)) |val| {
...@@ -3724,12 +3725,12 @@ fn zirAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -3724,12 +3725,12 @@ fn zirAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
3724 const ty_src: LazySrcLoc = .{ .node_offset_var_decl_ty = inst_data.src_node };3725 const ty_src: LazySrcLoc = .{ .node_offset_var_decl_ty = inst_data.src_node };
3725 const var_ty = try sema.resolveType(block, ty_src, inst_data.operand);3726 const var_ty = try sema.resolveType(block, ty_src, inst_data.operand);
3726 if (block.is_comptime) {3727 if (block.is_comptime) {
3727 return sema.analyzeComptimeAlloc(block, var_ty, 0);3728 return sema.analyzeComptimeAlloc(block, var_ty, .none);
3728 }3729 }
3729 const target = sema.mod.getTarget();3730 const target = sema.mod.getTarget();
3730 const ptr_type = try Type.ptr(sema.arena, sema.mod, .{3731 const ptr_type = try sema.mod.ptrType(.{
3731 .pointee_type = var_ty,3732 .child = var_ty.toIntern(),
3732 .@"addrspace" = target_util.defaultAddressSpace(target, .local),3733 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
3733 });3734 });
3734 try sema.queueFullTypeResolution(var_ty);3735 try sema.queueFullTypeResolution(var_ty);
3735 return block.addTy(.alloc, ptr_type);3736 return block.addTy(.alloc, ptr_type);
...@@ -3743,13 +3744,13 @@ fn zirAllocMut(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -3743,13 +3744,13 @@ fn zirAllocMut(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
3743 const ty_src: LazySrcLoc = .{ .node_offset_var_decl_ty = inst_data.src_node };3744 const ty_src: LazySrcLoc = .{ .node_offset_var_decl_ty = inst_data.src_node };
3744 const var_ty = try sema.resolveType(block, ty_src, inst_data.operand);3745 const var_ty = try sema.resolveType(block, ty_src, inst_data.operand);
3745 if (block.is_comptime) {3746 if (block.is_comptime) {
3746 return sema.analyzeComptimeAlloc(block, var_ty, 0);3747 return sema.analyzeComptimeAlloc(block, var_ty, .none);
3747 }3748 }
3748 try sema.validateVarType(block, ty_src, var_ty, false);3749 try sema.validateVarType(block, ty_src, var_ty, false);
3749 const target = sema.mod.getTarget();3750 const target = sema.mod.getTarget();
3750 const ptr_type = try Type.ptr(sema.arena, sema.mod, .{3751 const ptr_type = try sema.mod.ptrType(.{
3751 .pointee_type = var_ty,3752 .child = var_ty.toIntern(),
3752 .@"addrspace" = target_util.defaultAddressSpace(target, .local),3753 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
3753 });3754 });
3754 try sema.queueFullTypeResolution(var_ty);3755 try sema.queueFullTypeResolution(var_ty);
3755 return block.addTy(.alloc, ptr_type);3756 return block.addTy(.alloc, ptr_type);
...@@ -3915,11 +3916,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com...@@ -3915,11 +3916,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
3915 const new_decl_index = d: {3916 const new_decl_index = d: {
3916 var anon_decl = try block.startAnonDecl();3917 var anon_decl = try block.startAnonDecl();
3917 defer anon_decl.deinit();3918 defer anon_decl.deinit();
3918 const new_decl_index = try anon_decl.finish(3919 const new_decl_index = try anon_decl.finish(final_elem_ty, store_val, ia1.alignment);
3919 final_elem_ty,
3920 store_val,
3921 ia1.alignment.toByteUnits(0),
3922 );
3923 break :d new_decl_index;3920 break :d new_decl_index;
3924 };3921 };
3925 try mod.declareDeclDependency(sema.owner_decl_index, new_decl_index);3922 try mod.declareDeclDependency(sema.owner_decl_index, new_decl_index);
...@@ -5143,11 +5140,7 @@ fn storeToInferredAllocComptime(...@@ -5143,11 +5140,7 @@ fn storeToInferredAllocComptime(
5143 if (operand_val.getVariable(sema.mod) != null) break :store;5140 if (operand_val.getVariable(sema.mod) != null) break :store;
5144 var anon_decl = try block.startAnonDecl();5141 var anon_decl = try block.startAnonDecl();
5145 defer anon_decl.deinit();5142 defer anon_decl.deinit();
5146 iac.decl_index = try anon_decl.finish(5143 iac.decl_index = try anon_decl.finish(operand_ty, operand_val, iac.alignment);
5147 operand_ty,
5148 operand_val,
5149 iac.alignment.toByteUnits(0),
5150 );
5151 try sema.comptime_mutable_decls.append(iac.decl_index);5144 try sema.comptime_mutable_decls.append(iac.decl_index);
5152 return;5145 return;
5153 }5146 }
...@@ -5228,8 +5221,8 @@ fn addStrLit(sema: *Sema, block: *Block, bytes: []const u8) CompileError!Air.Ins...@@ -5228,8 +5221,8 @@ fn addStrLit(sema: *Sema, block: *Block, bytes: []const u8) CompileError!Air.Ins
5228 const duped_bytes = try sema.arena.dupe(u8, bytes);5221 const duped_bytes = try sema.arena.dupe(u8, bytes);
5229 const ty = try mod.arrayType(.{5222 const ty = try mod.arrayType(.{
5230 .len = bytes.len,5223 .len = bytes.len,
5231 .child = .u8_type,
5232 .sentinel = .zero_u8,5224 .sentinel = .zero_u8,
5225 .child = .u8_type,
5233 });5226 });
5234 const val = try mod.intern(.{ .aggregate = .{5227 const val = try mod.intern(.{ .aggregate = .{
5235 .ty = ty.toIntern(),5228 .ty = ty.toIntern(),
...@@ -5840,11 +5833,7 @@ fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -5840,11 +5833,7 @@ fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
5840 const decl_index = if (operand.val.getFunction(sema.mod)) |function| function.owner_decl else blk: {5833 const decl_index = if (operand.val.getFunction(sema.mod)) |function| function.owner_decl else blk: {
5841 var anon_decl = try block.startAnonDecl();5834 var anon_decl = try block.startAnonDecl();
5842 defer anon_decl.deinit();5835 defer anon_decl.deinit();
5843 break :blk try anon_decl.finish(5836 break :blk try anon_decl.finish(operand.ty, operand.val, .none);
5844 operand.ty,
5845 operand.val,
5846 0,
5847 );
5848 };5837 };
5849 try sema.analyzeExport(block, src, options, decl_index);5838 try sema.analyzeExport(block, src, options, decl_index);
5850}5839}
...@@ -5929,9 +5918,9 @@ fn zirSetAlignStack(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst...@@ -5929,9 +5918,9 @@ fn zirSetAlignStack(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst
5929 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };5918 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
5930 const src = LazySrcLoc.nodeOffset(extra.node);5919 const src = LazySrcLoc.nodeOffset(extra.node);
5931 const alignment = try sema.resolveAlign(block, operand_src, extra.operand);5920 const alignment = try sema.resolveAlign(block, operand_src, extra.operand);
5932 if (alignment > 256) {5921 if (alignment.order(Alignment.fromNonzeroByteUnits(256)).compare(.gt)) {
5933 return sema.fail(block, src, "attempt to @setAlignStack({d}); maximum is 256", .{5922 return sema.fail(block, src, "attempt to @setAlignStack({d}); maximum is 256", .{
5934 alignment,5923 alignment.toByteUnitsOptional().?,
5935 });5924 });
5936 }5925 }
5937 const func_index = sema.func_index.unwrap() orelse5926 const func_index = sema.func_index.unwrap() orelse
...@@ -6566,8 +6555,8 @@ fn checkCallArgumentCount(...@@ -6566,8 +6555,8 @@ fn checkCallArgumentCount(
6566 .Fn => break :func_ty callee_ty,6555 .Fn => break :func_ty callee_ty,
6567 .Pointer => {6556 .Pointer => {
6568 const ptr_info = callee_ty.ptrInfo(mod);6557 const ptr_info = callee_ty.ptrInfo(mod);
6569 if (ptr_info.size == .One and ptr_info.pointee_type.zigTypeTag(mod) == .Fn) {6558 if (ptr_info.flags.size == .One and ptr_info.child.toType().zigTypeTag(mod) == .Fn) {
6570 break :func_ty ptr_info.pointee_type;6559 break :func_ty ptr_info.child.toType();
6571 }6560 }
6572 },6561 },
6573 .Optional => {6562 .Optional => {
...@@ -6638,8 +6627,8 @@ fn callBuiltin(...@@ -6638,8 +6627,8 @@ fn callBuiltin(
6638 .Fn => break :func_ty callee_ty,6627 .Fn => break :func_ty callee_ty,
6639 .Pointer => {6628 .Pointer => {
6640 const ptr_info = callee_ty.ptrInfo(mod);6629 const ptr_info = callee_ty.ptrInfo(mod);
6641 if (ptr_info.size == .One and ptr_info.pointee_type.zigTypeTag(mod) == .Fn) {6630 if (ptr_info.flags.size == .One and ptr_info.child.toType().zigTypeTag(mod) == .Fn) {
6642 break :func_ty ptr_info.pointee_type;6631 break :func_ty ptr_info.child.toType();
6643 }6632 }
6644 },6633 },
6645 else => {},6634 else => {},
...@@ -7877,7 +7866,7 @@ fn resolveGenericInstantiationType(...@@ -7877,7 +7866,7 @@ fn resolveGenericInstantiationType(
7877 .ty = new_decl.ty.toIntern(),7866 .ty = new_decl.ty.toIntern(),
7878 .index = new_func,7867 .index = new_func,
7879 } })).toValue();7868 } })).toValue();
7880 new_decl.@"align" = 0;7869 new_decl.alignment = .none;
7881 new_decl.has_tv = true;7870 new_decl.has_tv = true;
7882 new_decl.owns_tv = true;7871 new_decl.owns_tv = true;
7883 new_decl.analysis = .complete;7872 new_decl.analysis = .complete;
...@@ -7952,7 +7941,7 @@ fn zirOptionalType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -7952,7 +7941,7 @@ fn zirOptionalType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
7952 } else if (child_type.zigTypeTag(mod) == .Null) {7941 } else if (child_type.zigTypeTag(mod) == .Null) {
7953 return sema.fail(block, operand_src, "type '{}' cannot be optional", .{child_type.fmt(mod)});7942 return sema.fail(block, operand_src, "type '{}' cannot be optional", .{child_type.fmt(mod)});
7954 }7943 }
7955 const opt_type = try Type.optional(sema.arena, child_type, mod);7944 const opt_type = try mod.optionalType(child_type.toIntern());
79567945
7957 return sema.addType(opt_type);7946 return sema.addType(opt_type);
7958}7947}
...@@ -7998,7 +7987,10 @@ fn zirArrayType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -7998,7 +7987,10 @@ fn zirArrayType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
7998 const len = try sema.resolveInt(block, len_src, extra.lhs, Type.usize, "array length must be comptime-known");7987 const len = try sema.resolveInt(block, len_src, extra.lhs, Type.usize, "array length must be comptime-known");
7999 const elem_type = try sema.resolveType(block, elem_src, extra.rhs);7988 const elem_type = try sema.resolveType(block, elem_src, extra.rhs);
8000 try sema.validateArrayElemType(block, elem_type, elem_src);7989 try sema.validateArrayElemType(block, elem_type, elem_src);
8001 const array_ty = try Type.array(sema.arena, len, null, elem_type, sema.mod);7990 const array_ty = try sema.mod.arrayType(.{
7991 .len = len,
7992 .child = elem_type.toIntern(),
7993 });
80027994
8003 return sema.addType(array_ty);7995 return sema.addType(array_ty);
8004}7996}
...@@ -8018,7 +8010,11 @@ fn zirArrayTypeSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil...@@ -8018,7 +8010,11 @@ fn zirArrayTypeSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil
8018 const uncasted_sentinel = try sema.resolveInst(extra.sentinel);8010 const uncasted_sentinel = try sema.resolveInst(extra.sentinel);
8019 const sentinel = try sema.coerce(block, elem_type, uncasted_sentinel, sentinel_src);8011 const sentinel = try sema.coerce(block, elem_type, uncasted_sentinel, sentinel_src);
8020 const sentinel_val = try sema.resolveConstValue(block, sentinel_src, sentinel, "array sentinel value must be comptime-known");8012 const sentinel_val = try sema.resolveConstValue(block, sentinel_src, sentinel, "array sentinel value must be comptime-known");
8021 const array_ty = try Type.array(sema.arena, len, sentinel_val, elem_type, sema.mod);8013 const array_ty = try sema.mod.arrayType(.{
8014 .len = len,
8015 .sentinel = sentinel_val.toIntern(),
8016 .child = elem_type.toIntern(),
8017 });
80228018
8023 return sema.addType(array_ty);8019 return sema.addType(array_ty);
8024}8020}
...@@ -8393,10 +8389,12 @@ fn analyzeOptionalPayloadPtr(...@@ -8393,10 +8389,12 @@ fn analyzeOptionalPayloadPtr(
8393 }8389 }
83948390
8395 const child_type = opt_type.optionalChild(mod);8391 const child_type = opt_type.optionalChild(mod);
8396 const child_pointer = try Type.ptr(sema.arena, mod, .{8392 const child_pointer = try mod.ptrType(.{
8397 .pointee_type = child_type,8393 .child = child_type.toIntern(),
8398 .mutable = !optional_ptr_ty.isConstPtr(mod),8394 .flags = .{
8399 .@"addrspace" = optional_ptr_ty.ptrAddressSpace(mod),8395 .is_const = optional_ptr_ty.isConstPtr(mod),
8396 .address_space = optional_ptr_ty.ptrAddressSpace(mod),
8397 },
8400 });8398 });
84018399
8402 if (try sema.resolveDefinedValue(block, src, optional_ptr)) |ptr_val| {8400 if (try sema.resolveDefinedValue(block, src, optional_ptr)) |ptr_val| {
...@@ -8460,14 +8458,15 @@ fn zirOptionalPayload(...@@ -8460,14 +8458,15 @@ fn zirOptionalPayload(
8460 // TODO https://github.com/ziglang/zig/issues/65978458 // TODO https://github.com/ziglang/zig/issues/6597
8461 if (true) break :t operand_ty;8459 if (true) break :t operand_ty;
8462 const ptr_info = operand_ty.ptrInfo(mod);8460 const ptr_info = operand_ty.ptrInfo(mod);
8463 break :t try Type.ptr(sema.arena, mod, .{8461 break :t try mod.ptrType(.{
8464 .pointee_type = ptr_info.pointee_type,8462 .child = ptr_info.child,
8465 .@"align" = ptr_info.@"align",8463 .flags = .{
8466 .@"addrspace" = ptr_info.@"addrspace",8464 .alignment = ptr_info.flags.alignment,
8467 .mutable = ptr_info.mutable,8465 .is_const = ptr_info.flags.is_const,
8468 .@"allowzero" = ptr_info.@"allowzero",8466 .is_volatile = ptr_info.flags.is_volatile,
8469 .@"volatile" = ptr_info.@"volatile",8467 .is_allowzero = ptr_info.flags.is_allowzero,
8470 .size = .One,8468 .address_space = ptr_info.flags.address_space,
8469 },
8471 });8470 });
8472 },8471 },
8473 else => return sema.failWithExpectedOptionalType(block, src, operand_ty),8472 else => return sema.failWithExpectedOptionalType(block, src, operand_ty),
...@@ -8580,10 +8579,12 @@ fn analyzeErrUnionPayloadPtr(...@@ -8580,10 +8579,12 @@ fn analyzeErrUnionPayloadPtr(
85808579
8581 const err_union_ty = operand_ty.childType(mod);8580 const err_union_ty = operand_ty.childType(mod);
8582 const payload_ty = err_union_ty.errorUnionPayload(mod);8581 const payload_ty = err_union_ty.errorUnionPayload(mod);
8583 const operand_pointer_ty = try Type.ptr(sema.arena, mod, .{8582 const operand_pointer_ty = try mod.ptrType(.{
8584 .pointee_type = payload_ty,8583 .child = payload_ty.toIntern(),
8585 .mutable = !operand_ty.isConstPtr(mod),8584 .flags = .{
8586 .@"addrspace" = operand_ty.ptrAddressSpace(mod),8585 .is_const = operand_ty.isConstPtr(mod),
8586 .address_space = operand_ty.ptrAddressSpace(mod),
8587 },
8587 });8588 });
85888589
8589 if (try sema.resolveDefinedValue(block, src, operand)) |ptr_val| {8590 if (try sema.resolveDefinedValue(block, src, operand)) |ptr_val| {
...@@ -8750,7 +8751,7 @@ fn zirFunc(...@@ -8750,7 +8751,7 @@ fn zirFunc(
8750 block,8751 block,
8751 inst_data.src_node,8752 inst_data.src_node,
8752 inst,8753 inst,
8753 0,8754 .none,
8754 target_util.defaultAddressSpace(target, .function),8755 target_util.defaultAddressSpace(target, .function),
8755 FuncLinkSection.default,8756 FuncLinkSection.default,
8756 cc,8757 cc,
...@@ -8879,7 +8880,7 @@ fn funcCommon(...@@ -8879,7 +8880,7 @@ fn funcCommon(
8879 src_node_offset: i32,8880 src_node_offset: i32,
8880 func_inst: Zir.Inst.Index,8881 func_inst: Zir.Inst.Index,
8881 /// null means generic poison8882 /// null means generic poison
8882 alignment: ?u32,8883 alignment: ?Alignment,
8883 /// null means generic poison8884 /// null means generic poison
8884 address_space: ?std.builtin.AddressSpace,8885 address_space: ?std.builtin.AddressSpace,
8885 /// outer null means generic poison; inner null means default link section8886 /// outer null means generic poison; inner null means default link section
...@@ -9128,7 +9129,7 @@ fn funcCommon(...@@ -9128,7 +9129,7 @@ fn funcCommon(
9128 .return_type = return_type.toIntern(),9129 .return_type = return_type.toIntern(),
9129 .cc = cc_resolved,9130 .cc = cc_resolved,
9130 .cc_is_generic = cc == null,9131 .cc_is_generic = cc == null,
9131 .alignment = if (alignment) |a| InternPool.Alignment.fromByteUnits(a) else .none,9132 .alignment = alignment orelse .none,
9132 .align_is_generic = alignment == null,9133 .align_is_generic = alignment == null,
9133 .section_is_generic = section == .generic,9134 .section_is_generic = section == .generic,
9134 .addrspace_is_generic = address_space == null,9135 .addrspace_is_generic = address_space == null,
...@@ -9143,7 +9144,7 @@ fn funcCommon(...@@ -9143,7 +9144,7 @@ fn funcCommon(
9143 .default => .none,9144 .default => .none,
9144 .explicit => |section_name| section_name.toOptional(),9145 .explicit => |section_name| section_name.toOptional(),
9145 };9146 };
9146 sema.owner_decl.@"align" = alignment orelse 0;9147 sema.owner_decl.alignment = alignment orelse .none;
9147 sema.owner_decl.@"addrspace" = address_space orelse .generic;9148 sema.owner_decl.@"addrspace" = address_space orelse .generic;
91489149
9149 if (is_extern) {9150 if (is_extern) {
...@@ -10275,11 +10276,13 @@ const SwitchProngAnalysis = struct {...@@ -10275,11 +10276,13 @@ const SwitchProngAnalysis = struct {
10275 const union_obj = mod.typeToUnion(operand_ty).?;10276 const union_obj = mod.typeToUnion(operand_ty).?;
10276 const field_ty = union_obj.fields.values()[field_index].ty;10277 const field_ty = union_obj.fields.values()[field_index].ty;
10277 if (capture_byref) {10278 if (capture_byref) {
10278 const ptr_field_ty = try Type.ptr(sema.arena, mod, .{10279 const ptr_field_ty = try mod.ptrType(.{
10279 .pointee_type = field_ty,10280 .child = field_ty.toIntern(),
10280 .mutable = operand_ptr_ty.ptrIsMutable(mod),10281 .flags = .{
10281 .@"volatile" = operand_ptr_ty.isVolatilePtr(mod),10282 .is_const = !operand_ptr_ty.ptrIsMutable(mod),
10282 .@"addrspace" = operand_ptr_ty.ptrAddressSpace(mod),10283 .is_volatile = operand_ptr_ty.isVolatilePtr(mod),
10284 .address_space = operand_ptr_ty.ptrAddressSpace(mod),
10285 },
10283 });10286 });
10284 if (try sema.resolveDefinedValue(block, sema.src, spa.operand_ptr)) |union_ptr| {10287 if (try sema.resolveDefinedValue(block, sema.src, spa.operand_ptr)) |union_ptr| {
10285 return sema.addConstant(10288 return sema.addConstant(
...@@ -10382,24 +10385,28 @@ const SwitchProngAnalysis = struct {...@@ -10382,24 +10385,28 @@ const SwitchProngAnalysis = struct {
10382 // By-reference captures have some further restrictions which make them easier to emit10385 // By-reference captures have some further restrictions which make them easier to emit
10383 if (capture_byref) {10386 if (capture_byref) {
10384 const operand_ptr_info = operand_ptr_ty.ptrInfo(mod);10387 const operand_ptr_info = operand_ptr_ty.ptrInfo(mod);
10385 const capture_ptr_ty = try Type.ptr(sema.arena, sema.mod, .{10388 const capture_ptr_ty = try mod.ptrType(.{
10386 .pointee_type = capture_ty,10389 .child = capture_ty.toIntern(),
10387 .@"addrspace" = operand_ptr_info.@"addrspace",10390 .flags = .{
10388 .mutable = operand_ptr_info.mutable,10391 // TODO: alignment!
10389 .@"volatile" = operand_ptr_info.@"volatile",10392 .is_const = operand_ptr_info.flags.is_const,
10390 // TODO: alignment!10393 .is_volatile = operand_ptr_info.flags.is_volatile,
10394 .address_space = operand_ptr_info.flags.address_space,
10395 },
10391 });10396 });
1039210397
10393 // By-ref captures of hetereogeneous types are only allowed if each field10398 // By-ref captures of hetereogeneous types are only allowed if each field
10394 // pointer type is in-memory coercible to the capture pointer type.10399 // pointer type is in-memory coercible to the capture pointer type.
10395 if (!same_types) {10400 if (!same_types) {
10396 for (field_tys, 0..) |field_ty, i| {10401 for (field_tys, 0..) |field_ty, i| {
10397 const field_ptr_ty = try Type.ptr(sema.arena, sema.mod, .{10402 const field_ptr_ty = try mod.ptrType(.{
10398 .pointee_type = field_ty,10403 .child = field_ty.toIntern(),
10399 .@"addrspace" = operand_ptr_info.@"addrspace",10404 .flags = .{
10400 .mutable = operand_ptr_info.mutable,10405 // TODO: alignment!
10401 .@"volatile" = operand_ptr_info.@"volatile",10406 .is_const = operand_ptr_info.flags.is_const,
10402 // TODO: alignment!10407 .is_volatile = operand_ptr_info.flags.is_volatile,
10408 .address_space = operand_ptr_info.flags.address_space,
10409 },
10403 });10410 });
10404 if (.ok != try sema.coerceInMemoryAllowed(block, capture_ptr_ty, field_ptr_ty, false, sema.mod.getTarget(), .unneeded, .unneeded)) {10411 if (.ok != try sema.coerceInMemoryAllowed(block, capture_ptr_ty, field_ptr_ty, false, sema.mod.getTarget(), .unneeded, .unneeded)) {
10405 const multi_idx = raw_capture_src.multi_capture;10412 const multi_idx = raw_capture_src.multi_capture;
...@@ -12656,8 +12663,8 @@ fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -12656,8 +12663,8 @@ fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
12656 // - When a Decl is destroyed, it can free the `*Module.EmbedFile`.12663 // - When a Decl is destroyed, it can free the `*Module.EmbedFile`.
12657 const ty = try mod.arrayType(.{12664 const ty = try mod.arrayType(.{
12658 .len = embed_file.bytes.len,12665 .len = embed_file.bytes.len,
12659 .child = .u8_type,
12660 .sentinel = .zero_u8,12666 .sentinel = .zero_u8,
12667 .child = .u8_type,
12661 });12668 });
12662 embed_file.owner_decl = try anon_decl.finish(12669 embed_file.owner_decl = try anon_decl.finish(
12663 ty,12670 ty,
...@@ -12665,7 +12672,7 @@ fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -12665,7 +12672,7 @@ fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
12665 .ty = ty.toIntern(),12672 .ty = ty.toIntern(),
12666 .storage = .{ .bytes = embed_file.bytes },12673 .storage = .{ .bytes = embed_file.bytes },
12667 } })).toValue(),12674 } })).toValue(),
12668 0, // default alignment12675 .none, // default alignment
12669 );12676 );
1267012677
12671 return sema.analyzeDeclRef(embed_file.owner_decl);12678 return sema.analyzeDeclRef(embed_file.owner_decl);
...@@ -13289,7 +13296,11 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13289,7 +13296,11 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13289 ),13296 ),
13290 };13297 };
1329113298
13292 const result_ty = try Type.array(sema.arena, result_len, res_sent_val, resolved_elem_ty, mod);13299 const result_ty = try mod.arrayType(.{
13300 .len = result_len,
13301 .sentinel = if (res_sent_val) |v| v.toIntern() else .none,
13302 .child = resolved_elem_ty.toIntern(),
13303 });
13293 const ptr_addrspace = p: {13304 const ptr_addrspace = p: {
13294 if (lhs_ty.zigTypeTag(mod) == .Pointer) break :p lhs_ty.ptrAddressSpace(mod);13305 if (lhs_ty.zigTypeTag(mod) == .Pointer) break :p lhs_ty.ptrAddressSpace(mod);
13295 if (rhs_ty.zigTypeTag(mod) == .Pointer) break :p rhs_ty.ptrAddressSpace(mod);13306 if (rhs_ty.zigTypeTag(mod) == .Pointer) break :p rhs_ty.ptrAddressSpace(mod);
...@@ -13348,14 +13359,14 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13348,14 +13359,14 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13348 try sema.requireRuntimeBlock(block, src, runtime_src);13359 try sema.requireRuntimeBlock(block, src, runtime_src);
1334913360
13350 if (ptr_addrspace) |ptr_as| {13361 if (ptr_addrspace) |ptr_as| {
13351 const alloc_ty = try Type.ptr(sema.arena, mod, .{13362 const alloc_ty = try mod.ptrType(.{
13352 .pointee_type = result_ty,13363 .child = result_ty.toIntern(),
13353 .@"addrspace" = ptr_as,13364 .flags = .{ .address_space = ptr_as },
13354 });13365 });
13355 const alloc = try block.addTy(.alloc, alloc_ty);13366 const alloc = try block.addTy(.alloc, alloc_ty);
13356 const elem_ptr_ty = try Type.ptr(sema.arena, mod, .{13367 const elem_ptr_ty = try mod.ptrType(.{
13357 .pointee_type = resolved_elem_ty,13368 .child = resolved_elem_ty.toIntern(),
13358 .@"addrspace" = ptr_as,13369 .flags = .{ .address_space = ptr_as },
13359 });13370 });
1336013371
13361 var elem_i: usize = 0;13372 var elem_i: usize = 0;
...@@ -13407,21 +13418,24 @@ fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Ins...@@ -13407,21 +13418,24 @@ fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Ins
13407 .Array => return operand_ty.arrayInfo(mod),13418 .Array => return operand_ty.arrayInfo(mod),
13408 .Pointer => {13419 .Pointer => {
13409 const ptr_info = operand_ty.ptrInfo(mod);13420 const ptr_info = operand_ty.ptrInfo(mod);
13410 switch (ptr_info.size) {13421 switch (ptr_info.flags.size) {
13411 // TODO: in the Many case here this should only work if the type13422 // TODO: in the Many case here this should only work if the type
13412 // has a sentinel, and this code should compute the length based13423 // has a sentinel, and this code should compute the length based
13413 // on the sentinel value.13424 // on the sentinel value.
13414 .Slice, .Many => {13425 .Slice, .Many => {
13415 const val = try sema.resolveConstValue(block, src, operand, "slice value being concatenated must be comptime-known");13426 const val = try sema.resolveConstValue(block, src, operand, "slice value being concatenated must be comptime-known");
13416 return Type.ArrayInfo{13427 return Type.ArrayInfo{
13417 .elem_type = ptr_info.pointee_type,13428 .elem_type = ptr_info.child.toType(),
13418 .sentinel = ptr_info.sentinel,13429 .sentinel = switch (ptr_info.sentinel) {
13430 .none => null,
13431 else => ptr_info.sentinel.toValue(),
13432 },
13419 .len = val.sliceLen(mod),13433 .len = val.sliceLen(mod),
13420 };13434 };
13421 },13435 },
13422 .One => {13436 .One => {
13423 if (ptr_info.pointee_type.zigTypeTag(mod) == .Array) {13437 if (ptr_info.child.toType().zigTypeTag(mod) == .Array) {
13424 return ptr_info.pointee_type.arrayInfo(mod);13438 return ptr_info.child.toType().arrayInfo(mod);
13425 }13439 }
13426 },13440 },
13427 .C => {},13441 .C => {},
...@@ -13557,7 +13571,11 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13557,7 +13571,11 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13557 return sema.fail(block, rhs_src, "operation results in overflow", .{});13571 return sema.fail(block, rhs_src, "operation results in overflow", .{});
13558 const result_len = try sema.usizeCast(block, src, result_len_u64);13572 const result_len = try sema.usizeCast(block, src, result_len_u64);
1355913573
13560 const result_ty = try Type.array(sema.arena, result_len, lhs_info.sentinel, lhs_info.elem_type, mod);13574 const result_ty = try mod.arrayType(.{
13575 .len = result_len,
13576 .sentinel = if (lhs_info.sentinel) |s| s.toIntern() else .none,
13577 .child = lhs_info.elem_type.toIntern(),
13578 });
1356113579
13562 const ptr_addrspace = if (lhs_ty.zigTypeTag(mod) == .Pointer) lhs_ty.ptrAddressSpace(mod) else null;13580 const ptr_addrspace = if (lhs_ty.zigTypeTag(mod) == .Pointer) lhs_ty.ptrAddressSpace(mod) else null;
13563 const lhs_len = try sema.usizeCast(block, lhs_src, lhs_info.len);13581 const lhs_len = try sema.usizeCast(block, lhs_src, lhs_info.len);
...@@ -13600,14 +13618,14 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13600,14 +13618,14 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13600 try sema.requireRuntimeBlock(block, src, lhs_src);13618 try sema.requireRuntimeBlock(block, src, lhs_src);
1360113619
13602 if (ptr_addrspace) |ptr_as| {13620 if (ptr_addrspace) |ptr_as| {
13603 const alloc_ty = try Type.ptr(sema.arena, mod, .{13621 const alloc_ty = try mod.ptrType(.{
13604 .pointee_type = result_ty,13622 .child = result_ty.toIntern(),
13605 .@"addrspace" = ptr_as,13623 .flags = .{ .address_space = ptr_as },
13606 });13624 });
13607 const alloc = try block.addTy(.alloc, alloc_ty);13625 const alloc = try block.addTy(.alloc, alloc_ty);
13608 const elem_ptr_ty = try Type.ptr(sema.arena, mod, .{13626 const elem_ptr_ty = try mod.ptrType(.{
13609 .pointee_type = lhs_info.elem_type,13627 .child = lhs_info.elem_type.toIntern(),
13610 .@"addrspace" = ptr_as,13628 .flags = .{ .address_space = ptr_as },
13611 });13629 });
1361213630
13613 var elem_i: usize = 0;13631 var elem_i: usize = 0;
...@@ -15563,18 +15581,18 @@ fn analyzePtrArithmetic(...@@ -15563,18 +15581,18 @@ fn analyzePtrArithmetic(
15563 const opt_off_val = try sema.resolveDefinedValue(block, offset_src, offset);15581 const opt_off_val = try sema.resolveDefinedValue(block, offset_src, offset);
15564 const ptr_ty = sema.typeOf(ptr);15582 const ptr_ty = sema.typeOf(ptr);
15565 const ptr_info = ptr_ty.ptrInfo(mod);15583 const ptr_info = ptr_ty.ptrInfo(mod);
15566 assert(ptr_info.size == .Many or ptr_info.size == .C);15584 assert(ptr_info.flags.size == .Many or ptr_info.flags.size == .C);
1556715585
15568 const new_ptr_ty = t: {15586 const new_ptr_ty = t: {
15569 // Calculate the new pointer alignment.15587 // Calculate the new pointer alignment.
15570 // This code is duplicated in `elemPtrType`.15588 // This code is duplicated in `elemPtrType`.
15571 if (ptr_info.@"align" == 0) {15589 if (ptr_info.flags.alignment == .none) {
15572 // ABI-aligned pointer. Any pointer arithmetic maintains the same ABI-alignedness.15590 // ABI-aligned pointer. Any pointer arithmetic maintains the same ABI-alignedness.
15573 break :t ptr_ty;15591 break :t ptr_ty;
15574 }15592 }
15575 // If the addend is not a comptime-known value we can still count on15593 // If the addend is not a comptime-known value we can still count on
15576 // it being a multiple of the type size.15594 // it being a multiple of the type size.
15577 const elem_size = ptr_info.pointee_type.abiSize(mod);15595 const elem_size = ptr_info.child.toType().abiSize(mod);
15578 const addend = if (opt_off_val) |off_val| a: {15596 const addend = if (opt_off_val) |off_val| a: {
15579 const off_int = try sema.usizeCast(block, offset_src, off_val.toUnsignedInt(mod));15597 const off_int = try sema.usizeCast(block, offset_src, off_val.toUnsignedInt(mod));
15580 break :a elem_size * off_int;15598 break :a elem_size * off_int;
...@@ -15583,17 +15601,23 @@ fn analyzePtrArithmetic(...@@ -15583,17 +15601,23 @@ fn analyzePtrArithmetic(
15583 // The resulting pointer is aligned to the lcd between the offset (an15601 // The resulting pointer is aligned to the lcd between the offset (an
15584 // arbitrary number) and the alignment factor (always a power of two,15602 // arbitrary number) and the alignment factor (always a power of two,
15585 // non zero).15603 // non zero).
15586 const new_align = @as(u32, 1) << @intCast(u5, @ctz(addend | ptr_info.@"align"));15604 const new_align = @enumFromInt(Alignment, @min(
15605 @ctz(addend),
15606 @intFromEnum(ptr_info.flags.alignment),
15607 ));
15608 assert(new_align != .none);
1558715609
15588 break :t try Type.ptr(sema.arena, mod, .{15610 break :t try mod.ptrType(.{
15589 .pointee_type = ptr_info.pointee_type,15611 .child = ptr_info.child,
15590 .sentinel = ptr_info.sentinel,15612 .sentinel = ptr_info.sentinel,
15591 .@"align" = new_align,15613 .flags = .{
15592 .@"addrspace" = ptr_info.@"addrspace",15614 .size = ptr_info.flags.size,
15593 .mutable = ptr_info.mutable,15615 .alignment = new_align,
15594 .@"allowzero" = ptr_info.@"allowzero",15616 .is_const = ptr_info.flags.is_const,
15595 .@"volatile" = ptr_info.@"volatile",15617 .is_volatile = ptr_info.flags.is_volatile,
15596 .size = ptr_info.size,15618 .is_allowzero = ptr_info.flags.is_allowzero,
15619 .address_space = ptr_info.flags.address_space,
15620 },
15597 });15621 });
15598 };15622 };
1559915623
...@@ -15605,7 +15629,7 @@ fn analyzePtrArithmetic(...@@ -15605,7 +15629,7 @@ fn analyzePtrArithmetic(
15605 const offset_int = try sema.usizeCast(block, offset_src, offset_val.toUnsignedInt(mod));15629 const offset_int = try sema.usizeCast(block, offset_src, offset_val.toUnsignedInt(mod));
15606 if (offset_int == 0) return ptr;15630 if (offset_int == 0) return ptr;
15607 if (try ptr_val.getUnsignedIntAdvanced(mod, sema)) |addr| {15631 if (try ptr_val.getUnsignedIntAdvanced(mod, sema)) |addr| {
15608 const elem_size = ptr_info.pointee_type.abiSize(mod);15632 const elem_size = ptr_info.child.toType().abiSize(mod);
15609 const new_addr = switch (air_tag) {15633 const new_addr = switch (air_tag) {
15610 .ptr_add => addr + elem_size * offset_int,15634 .ptr_add => addr + elem_size * offset_int,
15611 .ptr_sub => addr - elem_size * offset_int,15635 .ptr_sub => addr - elem_size * offset_int,
...@@ -16344,8 +16368,8 @@ fn zirBuiltinSrc(...@@ -16344,8 +16368,8 @@ fn zirBuiltinSrc(
16344 const name = try sema.arena.dupe(u8, mod.intern_pool.stringToSlice(fn_owner_decl.name));16368 const name = try sema.arena.dupe(u8, mod.intern_pool.stringToSlice(fn_owner_decl.name));
16345 const new_decl_ty = try mod.arrayType(.{16369 const new_decl_ty = try mod.arrayType(.{
16346 .len = name.len,16370 .len = name.len,
16347 .child = .u8_type,
16348 .sentinel = .zero_u8,16371 .sentinel = .zero_u8,
16372 .child = .u8_type,
16349 });16373 });
16350 const new_decl = try anon_decl.finish(16374 const new_decl = try anon_decl.finish(
16351 new_decl_ty,16375 new_decl_ty,
...@@ -16353,7 +16377,7 @@ fn zirBuiltinSrc(...@@ -16353,7 +16377,7 @@ fn zirBuiltinSrc(
16353 .ty = new_decl_ty.toIntern(),16377 .ty = new_decl_ty.toIntern(),
16354 .storage = .{ .bytes = name },16378 .storage = .{ .bytes = name },
16355 } })).toValue(),16379 } })).toValue(),
16356 0, // default alignment16380 .none, // default alignment
16357 );16381 );
16358 break :blk try mod.intern(.{ .ptr = .{16382 break :blk try mod.intern(.{ .ptr = .{
16359 .ty = .slice_const_u8_sentinel_0_type,16383 .ty = .slice_const_u8_sentinel_0_type,
...@@ -16369,8 +16393,8 @@ fn zirBuiltinSrc(...@@ -16369,8 +16393,8 @@ fn zirBuiltinSrc(
16369 const name = try fn_owner_decl.getFileScope(mod).fullPathZ(sema.arena);16393 const name = try fn_owner_decl.getFileScope(mod).fullPathZ(sema.arena);
16370 const new_decl_ty = try mod.arrayType(.{16394 const new_decl_ty = try mod.arrayType(.{
16371 .len = name.len,16395 .len = name.len,
16372 .child = .u8_type,
16373 .sentinel = .zero_u8,16396 .sentinel = .zero_u8,
16397 .child = .u8_type,
16374 });16398 });
16375 const new_decl = try anon_decl.finish(16399 const new_decl = try anon_decl.finish(
16376 new_decl_ty,16400 new_decl_ty,
...@@ -16378,7 +16402,7 @@ fn zirBuiltinSrc(...@@ -16378,7 +16402,7 @@ fn zirBuiltinSrc(
16378 .ty = new_decl_ty.toIntern(),16402 .ty = new_decl_ty.toIntern(),
16379 .storage = .{ .bytes = name },16403 .storage = .{ .bytes = name },
16380 } })).toValue(),16404 } })).toValue(),
16381 0, // default alignment16405 .none, // default alignment
16382 );16406 );
16383 break :blk try mod.intern(.{ .ptr = .{16407 break :blk try mod.intern(.{ .ptr = .{
16384 .ty = .slice_const_u8_sentinel_0_type,16408 .ty = .slice_const_u8_sentinel_0_type,
...@@ -16499,7 +16523,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16499,7 +16523,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16499 .ty = new_decl_ty.toIntern(),16523 .ty = new_decl_ty.toIntern(),
16500 .storage = .{ .elems = param_vals },16524 .storage = .{ .elems = param_vals },
16501 } })).toValue(),16525 } })).toValue(),
16502 0, // default alignment16526 .none, // default alignment
16503 );16527 );
16504 break :v try mod.intern(.{ .ptr = .{16528 break :v try mod.intern(.{ .ptr = .{
16505 .ty = (try mod.ptrType(.{16529 .ty = (try mod.ptrType(.{
...@@ -16601,10 +16625,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16601,10 +16625,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16601 },16625 },
16602 .Pointer => {16626 .Pointer => {
16603 const info = ty.ptrInfo(mod);16627 const info = ty.ptrInfo(mod);
16604 const alignment = if (info.@"align" != 0)16628 const alignment = if (info.flags.alignment.toByteUnitsOptional()) |alignment|
16605 try mod.intValue(Type.comptime_int, info.@"align")16629 try mod.intValue(Type.comptime_int, alignment)
16606 else16630 else
16607 try info.pointee_type.lazyAbiAlignment(mod);16631 try info.child.toType().lazyAbiAlignment(mod);
1660816632
16609 const addrspace_ty = try sema.getBuiltinType("AddressSpace");16633 const addrspace_ty = try sema.getBuiltinType("AddressSpace");
16610 const pointer_ty = t: {16634 const pointer_ty = t: {
...@@ -16634,21 +16658,24 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16634,21 +16658,24 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1663416658
16635 const field_values = .{16659 const field_values = .{
16636 // size: Size,16660 // size: Size,
16637 try (try mod.enumValueFieldIndex(ptr_size_ty, @intFromEnum(info.size))).intern(ptr_size_ty, mod),16661 try (try mod.enumValueFieldIndex(ptr_size_ty, @intFromEnum(info.flags.size))).intern(ptr_size_ty, mod),
16638 // is_const: bool,16662 // is_const: bool,
16639 Value.makeBool(!info.mutable).toIntern(),16663 Value.makeBool(info.flags.is_const).toIntern(),
16640 // is_volatile: bool,16664 // is_volatile: bool,
16641 Value.makeBool(info.@"volatile").toIntern(),16665 Value.makeBool(info.flags.is_volatile).toIntern(),
16642 // alignment: comptime_int,16666 // alignment: comptime_int,
16643 alignment.toIntern(),16667 alignment.toIntern(),
16644 // address_space: AddressSpace16668 // address_space: AddressSpace
16645 try (try mod.enumValueFieldIndex(addrspace_ty, @intFromEnum(info.@"addrspace"))).intern(addrspace_ty, mod),16669 try (try mod.enumValueFieldIndex(addrspace_ty, @intFromEnum(info.flags.address_space))).intern(addrspace_ty, mod),
16646 // child: type,16670 // child: type,
16647 info.pointee_type.toIntern(),16671 info.child,
16648 // is_allowzero: bool,16672 // is_allowzero: bool,
16649 Value.makeBool(info.@"allowzero").toIntern(),16673 Value.makeBool(info.flags.is_allowzero).toIntern(),
16650 // sentinel: ?*const anyopaque,16674 // sentinel: ?*const anyopaque,
16651 (try sema.optRefValue(block, info.pointee_type, info.sentinel)).toIntern(),16675 (try sema.optRefValue(block, info.child.toType(), switch (info.sentinel) {
16676 .none => null,
16677 else => info.sentinel.toValue(),
16678 })).toIntern(),
16652 };16679 };
16653 return sema.addConstant(type_info_ty, (try mod.intern(.{ .un = .{16680 return sema.addConstant(type_info_ty, (try mod.intern(.{ .un = .{
16654 .ty = type_info_ty.toIntern(),16681 .ty = type_info_ty.toIntern(),
...@@ -16792,7 +16819,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16792,7 +16819,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16792 .ty = new_decl_ty.toIntern(),16819 .ty = new_decl_ty.toIntern(),
16793 .storage = .{ .bytes = name },16820 .storage = .{ .bytes = name },
16794 } })).toValue(),16821 } })).toValue(),
16795 0, // default alignment16822 .none, // default alignment
16796 );16823 );
16797 break :v try mod.intern(.{ .ptr = .{16824 break :v try mod.intern(.{ .ptr = .{
16798 .ty = .slice_const_u8_type,16825 .ty = .slice_const_u8_type,
...@@ -16827,7 +16854,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16827,7 +16854,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16827 const array_errors_ty = try mod.arrayType(.{16854 const array_errors_ty = try mod.arrayType(.{
16828 .len = vals.len,16855 .len = vals.len,
16829 .child = error_field_ty.toIntern(),16856 .child = error_field_ty.toIntern(),
16830 .sentinel = .none,
16831 });16857 });
16832 const new_decl = try fields_anon_decl.finish(16858 const new_decl = try fields_anon_decl.finish(
16833 array_errors_ty,16859 array_errors_ty,
...@@ -16835,7 +16861,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16835,7 +16861,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16835 .ty = array_errors_ty.toIntern(),16861 .ty = array_errors_ty.toIntern(),
16836 .storage = .{ .elems = vals },16862 .storage = .{ .elems = vals },
16837 } })).toValue(),16863 } })).toValue(),
16838 0, // default alignment16864 .none, // default alignment
16839 );16865 );
16840 break :v try mod.intern(.{ .ptr = .{16866 break :v try mod.intern(.{ .ptr = .{
16841 .ty = slice_errors_ty.toIntern(),16867 .ty = slice_errors_ty.toIntern(),
...@@ -16929,7 +16955,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16929,7 +16955,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16929 .ty = new_decl_ty.toIntern(),16955 .ty = new_decl_ty.toIntern(),
16930 .storage = .{ .bytes = name },16956 .storage = .{ .bytes = name },
16931 } })).toValue(),16957 } })).toValue(),
16932 0, // default alignment16958 .none, // default alignment
16933 );16959 );
16934 break :v try mod.intern(.{ .ptr = .{16960 break :v try mod.intern(.{ .ptr = .{
16935 .ty = .slice_const_u8_type,16961 .ty = .slice_const_u8_type,
...@@ -16954,7 +16980,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16954,7 +16980,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16954 const fields_array_ty = try mod.arrayType(.{16980 const fields_array_ty = try mod.arrayType(.{
16955 .len = enum_field_vals.len,16981 .len = enum_field_vals.len,
16956 .child = enum_field_ty.toIntern(),16982 .child = enum_field_ty.toIntern(),
16957 .sentinel = .none,
16958 });16983 });
16959 const new_decl = try fields_anon_decl.finish(16984 const new_decl = try fields_anon_decl.finish(
16960 fields_array_ty,16985 fields_array_ty,
...@@ -16962,7 +16987,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16962,7 +16987,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16962 .ty = fields_array_ty.toIntern(),16987 .ty = fields_array_ty.toIntern(),
16963 .storage = .{ .elems = enum_field_vals },16988 .storage = .{ .elems = enum_field_vals },
16964 } })).toValue(),16989 } })).toValue(),
16965 0, // default alignment16990 .none, // default alignment
16966 );16991 );
16967 break :v try mod.intern(.{ .ptr = .{16992 break :v try mod.intern(.{ .ptr = .{
16968 .ty = (try mod.ptrType(.{16993 .ty = (try mod.ptrType(.{
...@@ -17068,7 +17093,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17068,7 +17093,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17068 .ty = new_decl_ty.toIntern(),17093 .ty = new_decl_ty.toIntern(),
17069 .storage = .{ .bytes = name },17094 .storage = .{ .bytes = name },
17070 } })).toValue(),17095 } })).toValue(),
17071 0, // default alignment17096 .none, // default alignment
17072 );17097 );
17073 break :v try mod.intern(.{ .ptr = .{17098 break :v try mod.intern(.{ .ptr = .{
17074 .ty = .slice_const_u8_type,17099 .ty = .slice_const_u8_type,
...@@ -17100,7 +17125,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17100,7 +17125,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17100 const array_fields_ty = try mod.arrayType(.{17125 const array_fields_ty = try mod.arrayType(.{
17101 .len = union_field_vals.len,17126 .len = union_field_vals.len,
17102 .child = union_field_ty.toIntern(),17127 .child = union_field_ty.toIntern(),
17103 .sentinel = .none,
17104 });17128 });
17105 const new_decl = try fields_anon_decl.finish(17129 const new_decl = try fields_anon_decl.finish(
17106 array_fields_ty,17130 array_fields_ty,
...@@ -17108,7 +17132,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17108,7 +17132,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17108 .ty = array_fields_ty.toIntern(),17132 .ty = array_fields_ty.toIntern(),
17109 .storage = .{ .elems = union_field_vals },17133 .storage = .{ .elems = union_field_vals },
17110 } })).toValue(),17134 } })).toValue(),
17111 0, // default alignment17135 .none, // default alignment
17112 );17136 );
17113 break :v try mod.intern(.{ .ptr = .{17137 break :v try mod.intern(.{ .ptr = .{
17114 .ty = (try mod.ptrType(.{17138 .ty = (try mod.ptrType(.{
...@@ -17228,7 +17252,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17228,7 +17252,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17228 .ty = new_decl_ty.toIntern(),17252 .ty = new_decl_ty.toIntern(),
17229 .storage = .{ .bytes = bytes },17253 .storage = .{ .bytes = bytes },
17230 } })).toValue(),17254 } })).toValue(),
17231 0, // default alignment17255 .none, // default alignment
17232 );17256 );
17233 break :v try mod.intern(.{ .ptr = .{17257 break :v try mod.intern(.{ .ptr = .{
17234 .ty = .slice_const_u8_type,17258 .ty = .slice_const_u8_type,
...@@ -17285,7 +17309,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17285,7 +17309,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17285 .ty = new_decl_ty.toIntern(),17309 .ty = new_decl_ty.toIntern(),
17286 .storage = .{ .bytes = name },17310 .storage = .{ .bytes = name },
17287 } })).toValue(),17311 } })).toValue(),
17288 0, // default alignment17312 .none, // default alignment
17289 );17313 );
17290 break :v try mod.intern(.{ .ptr = .{17314 break :v try mod.intern(.{ .ptr = .{
17291 .ty = .slice_const_u8_type,17315 .ty = .slice_const_u8_type,
...@@ -17324,7 +17348,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17324,7 +17348,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17324 const array_fields_ty = try mod.arrayType(.{17348 const array_fields_ty = try mod.arrayType(.{
17325 .len = struct_field_vals.len,17349 .len = struct_field_vals.len,
17326 .child = struct_field_ty.toIntern(),17350 .child = struct_field_ty.toIntern(),
17327 .sentinel = .none,
17328 });17351 });
17329 const new_decl = try fields_anon_decl.finish(17352 const new_decl = try fields_anon_decl.finish(
17330 array_fields_ty,17353 array_fields_ty,
...@@ -17332,7 +17355,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17332,7 +17355,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17332 .ty = array_fields_ty.toIntern(),17355 .ty = array_fields_ty.toIntern(),
17333 .storage = .{ .elems = struct_field_vals },17356 .storage = .{ .elems = struct_field_vals },
17334 } })).toValue(),17357 } })).toValue(),
17335 0, // default alignment17358 .none, // default alignment
17336 );17359 );
17337 break :v try mod.intern(.{ .ptr = .{17360 break :v try mod.intern(.{ .ptr = .{
17338 .ty = (try mod.ptrType(.{17361 .ty = (try mod.ptrType(.{
...@@ -17471,7 +17494,6 @@ fn typeInfoDecls(...@@ -17471,7 +17494,6 @@ fn typeInfoDecls(
17471 const array_decl_ty = try mod.arrayType(.{17494 const array_decl_ty = try mod.arrayType(.{
17472 .len = decl_vals.items.len,17495 .len = decl_vals.items.len,
17473 .child = declaration_ty.toIntern(),17496 .child = declaration_ty.toIntern(),
17474 .sentinel = .none,
17475 });17497 });
17476 const new_decl = try decls_anon_decl.finish(17498 const new_decl = try decls_anon_decl.finish(
17477 array_decl_ty,17499 array_decl_ty,
...@@ -17479,7 +17501,7 @@ fn typeInfoDecls(...@@ -17479,7 +17501,7 @@ fn typeInfoDecls(
17479 .ty = array_decl_ty.toIntern(),17501 .ty = array_decl_ty.toIntern(),
17480 .storage = .{ .elems = decl_vals.items },17502 .storage = .{ .elems = decl_vals.items },
17481 } })).toValue(),17503 } })).toValue(),
17482 0, // default alignment17504 .none, // default alignment
17483 );17505 );
17484 return try mod.intern(.{ .ptr = .{17506 return try mod.intern(.{ .ptr = .{
17485 .ty = (try mod.ptrType(.{17507 .ty = (try mod.ptrType(.{
...@@ -17532,7 +17554,7 @@ fn typeInfoNamespaceDecls(...@@ -17532,7 +17554,7 @@ fn typeInfoNamespaceDecls(
17532 .ty = new_decl_ty.toIntern(),17554 .ty = new_decl_ty.toIntern(),
17533 .storage = .{ .bytes = name },17555 .storage = .{ .bytes = name },
17534 } })).toValue(),17556 } })).toValue(),
17535 0, // default alignment17557 .none, // default alignment
17536 );17558 );
17537 break :v try mod.intern(.{ .ptr = .{17559 break :v try mod.intern(.{ .ptr = .{
17538 .ty = .slice_const_u8_type,17560 .ty = .slice_const_u8_type,
...@@ -18057,12 +18079,14 @@ fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErr...@@ -18057,12 +18079,14 @@ fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErr
1805718079
18058 const operand_ty = sema.typeOf(operand);18080 const operand_ty = sema.typeOf(operand);
18059 const ptr_info = operand_ty.ptrInfo(mod);18081 const ptr_info = operand_ty.ptrInfo(mod);
18060 const res_ty = try Type.ptr(sema.arena, mod, .{18082 const res_ty = try mod.ptrType(.{
18061 .pointee_type = err_union_ty.errorUnionPayload(mod),18083 .child = err_union_ty.errorUnionPayload(mod).toIntern(),
18062 .@"addrspace" = ptr_info.@"addrspace",18084 .flags = .{
18063 .mutable = ptr_info.mutable,18085 .is_const = ptr_info.flags.is_const,
18064 .@"allowzero" = ptr_info.@"allowzero",18086 .is_volatile = ptr_info.flags.is_volatile,
18065 .@"volatile" = ptr_info.@"volatile",18087 .is_allowzero = ptr_info.flags.is_allowzero,
18088 .address_space = ptr_info.flags.address_space,
18089 },
18066 });18090 });
18067 const res_ty_ref = try sema.addType(res_ty);18091 const res_ty_ref = try sema.addType(res_ty);
18068 try sema.air_extra.ensureUnusedCapacity(sema.gpa, @typeInfo(Air.TryPtr).Struct.fields.len +18092 try sema.air_extra.ensureUnusedCapacity(sema.gpa, @typeInfo(Air.TryPtr).Struct.fields.len +
...@@ -18482,7 +18506,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -18482,7 +18506,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
18482 break :blk val.toIntern();18506 break :blk val.toIntern();
18483 } else .none;18507 } else .none;
1848418508
18485 const abi_align: InternPool.Alignment = if (inst_data.flags.has_align) blk: {18509 const abi_align: Alignment = if (inst_data.flags.has_align) blk: {
18486 const ref = @enumFromInt(Zir.Inst.Ref, sema.code.extra[extra_i]);18510 const ref = @enumFromInt(Zir.Inst.Ref, sema.code.extra[extra_i]);
18487 extra_i += 1;18511 extra_i += 1;
18488 const coerced = try sema.coerce(block, Type.u32, try sema.resolveInst(ref), align_src);18512 const coerced = try sema.coerce(block, Type.u32, try sema.resolveInst(ref), align_src);
...@@ -18498,7 +18522,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -18498,7 +18522,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
18498 }18522 }
18499 const abi_align = @intCast(u32, (try val.getUnsignedIntAdvanced(mod, sema)).?);18523 const abi_align = @intCast(u32, (try val.getUnsignedIntAdvanced(mod, sema)).?);
18500 try sema.validateAlign(block, align_src, abi_align);18524 try sema.validateAlign(block, align_src, abi_align);
18501 break :blk InternPool.Alignment.fromByteUnits(abi_align);18525 break :blk Alignment.fromByteUnits(abi_align);
18502 } else .none;18526 } else .none;
1850318527
18504 const address_space: std.builtin.AddressSpace = if (inst_data.flags.has_addrspace) blk: {18528 const address_space: std.builtin.AddressSpace = if (inst_data.flags.has_addrspace) blk: {
...@@ -18775,9 +18799,9 @@ fn zirStructInit(...@@ -18775,9 +18799,9 @@ fn zirStructInit(
1877518799
18776 if (is_ref) {18800 if (is_ref) {
18777 const target = mod.getTarget();18801 const target = mod.getTarget();
18778 const alloc_ty = try Type.ptr(sema.arena, mod, .{18802 const alloc_ty = try mod.ptrType(.{
18779 .pointee_type = resolved_ty,18803 .child = resolved_ty.toIntern(),
18780 .@"addrspace" = target_util.defaultAddressSpace(target, .local),18804 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
18781 });18805 });
18782 const alloc = try block.addTy(.alloc, alloc_ty);18806 const alloc = try block.addTy(.alloc, alloc_ty);
18783 const field_ptr = try sema.unionFieldPtr(block, field_src, alloc, field_name, field_src, resolved_ty, true);18807 const field_ptr = try sema.unionFieldPtr(block, field_src, alloc, field_name, field_src, resolved_ty, true);
...@@ -18898,9 +18922,9 @@ fn finishStructInit(...@@ -18898,9 +18922,9 @@ fn finishStructInit(
18898 if (is_ref) {18922 if (is_ref) {
18899 try sema.resolveStructLayout(struct_ty);18923 try sema.resolveStructLayout(struct_ty);
18900 const target = sema.mod.getTarget();18924 const target = sema.mod.getTarget();
18901 const alloc_ty = try Type.ptr(sema.arena, mod, .{18925 const alloc_ty = try mod.ptrType(.{
18902 .pointee_type = struct_ty,18926 .child = struct_ty.toIntern(),
18903 .@"addrspace" = target_util.defaultAddressSpace(target, .local),18927 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
18904 });18928 });
18905 const alloc = try block.addTy(.alloc, alloc_ty);18929 const alloc = try block.addTy(.alloc, alloc_ty);
18906 for (field_inits, 0..) |field_init, i_usize| {18930 for (field_inits, 0..) |field_init, i_usize| {
...@@ -19019,9 +19043,9 @@ fn zirStructInitAnon(...@@ -19019,9 +19043,9 @@ fn zirStructInitAnon(
1901919043
19020 if (is_ref) {19044 if (is_ref) {
19021 const target = mod.getTarget();19045 const target = mod.getTarget();
19022 const alloc_ty = try Type.ptr(sema.arena, mod, .{19046 const alloc_ty = try mod.ptrType(.{
19023 .pointee_type = tuple_ty.toType(),19047 .child = tuple_ty,
19024 .@"addrspace" = target_util.defaultAddressSpace(target, .local),19048 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
19025 });19049 });
19026 const alloc = try block.addTy(.alloc, alloc_ty);19050 const alloc = try block.addTy(.alloc, alloc_ty);
19027 var extra_index = extra.end;19051 var extra_index = extra.end;
...@@ -19030,10 +19054,9 @@ fn zirStructInitAnon(...@@ -19030,10 +19054,9 @@ fn zirStructInitAnon(
19030 const item = sema.code.extraData(Zir.Inst.StructInitAnon.Item, extra_index);19054 const item = sema.code.extraData(Zir.Inst.StructInitAnon.Item, extra_index);
19031 extra_index = item.end;19055 extra_index = item.end;
1903219056
19033 const field_ptr_ty = try Type.ptr(sema.arena, mod, .{19057 const field_ptr_ty = try mod.ptrType(.{
19034 .mutable = true,19058 .child = field_ty,
19035 .@"addrspace" = target_util.defaultAddressSpace(target, .local),19059 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
19036 .pointee_type = field_ty.toType(),
19037 });19060 });
19038 if (values[i] == .none) {19061 if (values[i] == .none) {
19039 const init = try sema.resolveInst(item.data.init);19062 const init = try sema.resolveInst(item.data.init);
...@@ -19131,18 +19154,17 @@ fn zirArrayInit(...@@ -19131,18 +19154,17 @@ fn zirArrayInit(
1913119154
19132 if (is_ref) {19155 if (is_ref) {
19133 const target = mod.getTarget();19156 const target = mod.getTarget();
19134 const alloc_ty = try Type.ptr(sema.arena, mod, .{19157 const alloc_ty = try mod.ptrType(.{
19135 .pointee_type = array_ty,19158 .child = array_ty.toIntern(),
19136 .@"addrspace" = target_util.defaultAddressSpace(target, .local),19159 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
19137 });19160 });
19138 const alloc = try block.addTy(.alloc, alloc_ty);19161 const alloc = try block.addTy(.alloc, alloc_ty);
1913919162
19140 if (array_ty.isTuple(mod)) {19163 if (array_ty.isTuple(mod)) {
19141 for (resolved_args, 0..) |arg, i| {19164 for (resolved_args, 0..) |arg, i| {
19142 const elem_ptr_ty = try Type.ptr(sema.arena, mod, .{19165 const elem_ptr_ty = try mod.ptrType(.{
19143 .mutable = true,19166 .child = array_ty.structFieldType(i, mod).toIntern(),
19144 .@"addrspace" = target_util.defaultAddressSpace(target, .local),19167 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
19145 .pointee_type = array_ty.structFieldType(i, mod),
19146 });19168 });
19147 const elem_ptr_ty_ref = try sema.addType(elem_ptr_ty);19169 const elem_ptr_ty_ref = try sema.addType(elem_ptr_ty);
1914819170
...@@ -19153,10 +19175,9 @@ fn zirArrayInit(...@@ -19153,10 +19175,9 @@ fn zirArrayInit(
19153 return sema.makePtrConst(block, alloc);19175 return sema.makePtrConst(block, alloc);
19154 }19176 }
1915519177
19156 const elem_ptr_ty = try Type.ptr(sema.arena, mod, .{19178 const elem_ptr_ty = try mod.ptrType(.{
19157 .mutable = true,19179 .child = array_ty.elemType2(mod).toIntern(),
19158 .@"addrspace" = target_util.defaultAddressSpace(target, .local),19180 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
19159 .pointee_type = array_ty.elemType2(mod),
19160 });19181 });
19161 const elem_ptr_ty_ref = try sema.addType(elem_ptr_ty);19182 const elem_ptr_ty_ref = try sema.addType(elem_ptr_ty);
1916219183
...@@ -19230,17 +19251,16 @@ fn zirArrayInitAnon(...@@ -19230,17 +19251,16 @@ fn zirArrayInitAnon(
1923019251
19231 if (is_ref) {19252 if (is_ref) {
19232 const target = sema.mod.getTarget();19253 const target = sema.mod.getTarget();
19233 const alloc_ty = try Type.ptr(sema.arena, sema.mod, .{19254 const alloc_ty = try mod.ptrType(.{
19234 .pointee_type = tuple_ty.toType(),19255 .child = tuple_ty,
19235 .@"addrspace" = target_util.defaultAddressSpace(target, .local),19256 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
19236 });19257 });
19237 const alloc = try block.addTy(.alloc, alloc_ty);19258 const alloc = try block.addTy(.alloc, alloc_ty);
19238 for (operands, 0..) |operand, i_usize| {19259 for (operands, 0..) |operand, i_usize| {
19239 const i = @intCast(u32, i_usize);19260 const i = @intCast(u32, i_usize);
19240 const field_ptr_ty = try Type.ptr(sema.arena, sema.mod, .{19261 const field_ptr_ty = try mod.ptrType(.{
19241 .mutable = true,19262 .child = types[i],
19242 .@"addrspace" = target_util.defaultAddressSpace(target, .local),19263 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
19243 .pointee_type = types[i].toType(),
19244 });19264 });
19245 if (values[i] == .none) {19265 if (values[i] == .none) {
19246 const field_ptr = try block.addStructFieldPtr(alloc, i, field_ptr_ty);19266 const field_ptr = try block.addStructFieldPtr(alloc, i, field_ptr_ty);
...@@ -19273,7 +19293,7 @@ fn addConstantMaybeRef(...@@ -19273,7 +19293,7 @@ fn addConstantMaybeRef(
19273 const decl = try anon_decl.finish(19293 const decl = try anon_decl.finish(
19274 ty,19294 ty,
19275 val,19295 val,
19276 0, // default alignment19296 .none, // default alignment
19277 );19297 );
19278 return sema.analyzeDeclRef(decl);19298 return sema.analyzeDeclRef(decl);
19279}19299}
...@@ -19368,7 +19388,7 @@ fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {...@@ -19368,7 +19388,7 @@ fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {
19368 const unresolved_stack_trace_ty = try sema.getBuiltinType("StackTrace");19388 const unresolved_stack_trace_ty = try sema.getBuiltinType("StackTrace");
19369 const stack_trace_ty = try sema.resolveTypeFields(unresolved_stack_trace_ty);19389 const stack_trace_ty = try sema.resolveTypeFields(unresolved_stack_trace_ty);
19370 const ptr_stack_trace_ty = try mod.singleMutPtrType(stack_trace_ty);19390 const ptr_stack_trace_ty = try mod.singleMutPtrType(stack_trace_ty);
19371 const opt_ptr_stack_trace_ty = try Type.optional(sema.arena, ptr_stack_trace_ty, mod);19391 const opt_ptr_stack_trace_ty = try mod.optionalType(ptr_stack_trace_ty.toIntern());
1937219392
19373 if (sema.owner_func != null and19393 if (sema.owner_func != null and
19374 sema.owner_func.?.calls_or_awaits_errorable_fn and19394 sema.owner_func.?.calls_or_awaits_errorable_fn and
...@@ -19688,7 +19708,7 @@ fn zirReify(...@@ -19688,7 +19708,7 @@ fn zirReify(
19688 return sema.fail(block, src, "alignment must fit in 'u32'", .{});19708 return sema.fail(block, src, "alignment must fit in 'u32'", .{});
19689 }19709 }
1969019710
19691 const abi_align = InternPool.Alignment.fromByteUnits(19711 const abi_align = Alignment.fromByteUnits(
19692 (try alignment_val.getUnsignedIntAdvanced(mod, sema)).?,19712 (try alignment_val.getUnsignedIntAdvanced(mod, sema)).?,
19693 );19713 );
1969419714
...@@ -19709,10 +19729,7 @@ fn zirReify(...@@ -19709,10 +19729,7 @@ fn zirReify(
19709 return sema.fail(block, src, "sentinels are only allowed on slices and unknown-length pointers", .{});19729 return sema.fail(block, src, "sentinels are only allowed on slices and unknown-length pointers", .{});
19710 }19730 }
19711 const sentinel_ptr_val = sentinel_val.optionalValue(mod).?;19731 const sentinel_ptr_val = sentinel_val.optionalValue(mod).?;
19712 const ptr_ty = try Type.ptr(sema.arena, mod, .{19732 const ptr_ty = try mod.singleMutPtrType(elem_ty);
19713 .@"addrspace" = .generic,
19714 .pointee_type = elem_ty,
19715 });
19716 const sent_val = (try sema.pointerDeref(block, src, sentinel_ptr_val, ptr_ty)).?;19733 const sent_val = (try sema.pointerDeref(block, src, sentinel_ptr_val, ptr_ty)).?;
19717 break :s sent_val.toIntern();19734 break :s sent_val.toIntern();
19718 }19735 }
...@@ -19781,14 +19798,15 @@ fn zirReify(...@@ -19781,14 +19798,15 @@ fn zirReify(
19781 const len = len_val.toUnsignedInt(mod);19798 const len = len_val.toUnsignedInt(mod);
19782 const child_ty = child_val.toType();19799 const child_ty = child_val.toType();
19783 const sentinel = if (sentinel_val.optionalValue(mod)) |p| blk: {19800 const sentinel = if (sentinel_val.optionalValue(mod)) |p| blk: {
19784 const ptr_ty = try Type.ptr(sema.arena, mod, .{19801 const ptr_ty = try mod.singleMutPtrType(child_ty);
19785 .@"addrspace" = .generic,
19786 .pointee_type = child_ty,
19787 });
19788 break :blk (try sema.pointerDeref(block, src, p, ptr_ty)).?;19802 break :blk (try sema.pointerDeref(block, src, p, ptr_ty)).?;
19789 } else null;19803 } else null;
1979019804
19791 const ty = try Type.array(sema.arena, len, sentinel, child_ty, mod);19805 const ty = try mod.arrayType(.{
19806 .len = len,
19807 .sentinel = if (sentinel) |s| s.toIntern() else .none,
19808 .child = child_ty.toIntern(),
19809 });
19792 return sema.addType(ty);19810 return sema.addType(ty);
19793 },19811 },
19794 .Optional => {19812 .Optional => {
...@@ -19799,7 +19817,7 @@ fn zirReify(...@@ -19799,7 +19817,7 @@ fn zirReify(
1979919817
19800 const child_ty = child_val.toType();19818 const child_ty = child_val.toType();
1980119819
19802 const ty = try Type.optional(sema.arena, child_ty, mod);19820 const ty = try mod.optionalType(child_ty.toIntern());
19803 return sema.addType(ty);19821 return sema.addType(ty);
19804 },19822 },
19805 .ErrorUnion => {19823 .ErrorUnion => {
...@@ -20180,7 +20198,7 @@ fn zirReify(...@@ -20180,7 +20198,7 @@ fn zirReify(
20180 const field_ty = type_val.toType();20198 const field_ty = type_val.toType();
20181 gop.value_ptr.* = .{20199 gop.value_ptr.* = .{
20182 .ty = field_ty,20200 .ty = field_ty,
20183 .abi_align = @intCast(u32, (try alignment_val.getUnsignedIntAdvanced(mod, sema)).?),20201 .abi_align = Alignment.fromByteUnits((try alignment_val.getUnsignedIntAdvanced(mod, sema)).?),
20184 };20202 };
2018520203
20186 if (field_ty.zigTypeTag(mod) == .Opaque) {20204 if (field_ty.zigTypeTag(mod) == .Opaque) {
...@@ -20287,7 +20305,7 @@ fn zirReify(...@@ -20287,7 +20305,7 @@ fn zirReify(
20287 if (alignment == target_util.defaultFunctionAlignment(target)) {20305 if (alignment == target_util.defaultFunctionAlignment(target)) {
20288 break :alignment .none;20306 break :alignment .none;
20289 } else {20307 } else {
20290 break :alignment InternPool.Alignment.fromByteUnits(alignment);20308 break :alignment Alignment.fromByteUnits(alignment);
20291 }20309 }
20292 };20310 };
20293 const return_type = return_type_val.optionalValue(mod) orelse20311 const return_type = return_type_val.optionalValue(mod) orelse
...@@ -20436,7 +20454,7 @@ fn reifyStruct(...@@ -20436,7 +20454,7 @@ fn reifyStruct(
20436 if (!try sema.intFitsInType(alignment_val, Type.u32, null)) {20454 if (!try sema.intFitsInType(alignment_val, Type.u32, null)) {
20437 return sema.fail(block, src, "alignment must fit in 'u32'", .{});20455 return sema.fail(block, src, "alignment must fit in 'u32'", .{});
20438 }20456 }
20439 const abi_align = @intCast(u29, (try alignment_val.getUnsignedIntAdvanced(mod, sema)).?);20457 const abi_align = (try alignment_val.getUnsignedIntAdvanced(mod, sema)).?;
2044020458
20441 if (layout == .Packed) {20459 if (layout == .Packed) {
20442 if (abi_align != 0) return sema.fail(block, src, "alignment in a packed struct field must be set to 0", .{});20460 if (abi_align != 0) return sema.fail(block, src, "alignment in a packed struct field must be set to 0", .{});
...@@ -20483,7 +20501,7 @@ fn reifyStruct(...@@ -20483,7 +20501,7 @@ fn reifyStruct(
2048320501
20484 gop.value_ptr.* = .{20502 gop.value_ptr.* = .{
20485 .ty = field_ty,20503 .ty = field_ty,
20486 .abi_align = abi_align,20504 .abi_align = Alignment.fromByteUnits(abi_align),
20487 .default_val = default_val,20505 .default_val = default_val,
20488 .is_comptime = is_comptime_val.toBool(),20506 .is_comptime = is_comptime_val.toBool(),
20489 .offset = undefined,20507 .offset = undefined,
...@@ -20585,7 +20603,7 @@ fn zirAddrSpaceCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst...@@ -20585,7 +20603,7 @@ fn zirAddrSpaceCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst
20585 try sema.checkPtrOperand(block, ptr_src, ptr_ty);20603 try sema.checkPtrOperand(block, ptr_src, ptr_ty);
2058620604
20587 var ptr_info = ptr_ty.ptrInfo(mod);20605 var ptr_info = ptr_ty.ptrInfo(mod);
20588 const src_addrspace = ptr_info.@"addrspace";20606 const src_addrspace = ptr_info.flags.address_space;
20589 if (!target_util.addrSpaceCastIsValid(sema.mod.getTarget(), src_addrspace, dest_addrspace)) {20607 if (!target_util.addrSpaceCastIsValid(sema.mod.getTarget(), src_addrspace, dest_addrspace)) {
20590 const msg = msg: {20608 const msg = msg: {
20591 const msg = try sema.errMsg(block, src, "invalid address space cast", .{});20609 const msg = try sema.errMsg(block, src, "invalid address space cast", .{});
...@@ -20596,10 +20614,10 @@ fn zirAddrSpaceCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst...@@ -20596,10 +20614,10 @@ fn zirAddrSpaceCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst
20596 return sema.failWithOwnedErrorMsg(msg);20614 return sema.failWithOwnedErrorMsg(msg);
20597 }20615 }
2059820616
20599 ptr_info.@"addrspace" = dest_addrspace;20617 ptr_info.flags.address_space = dest_addrspace;
20600 const dest_ptr_ty = try Type.ptr(sema.arena, sema.mod, ptr_info);20618 const dest_ptr_ty = try mod.ptrType(ptr_info);
20601 const dest_ty = if (ptr_ty.zigTypeTag(mod) == .Optional)20619 const dest_ty = if (ptr_ty.zigTypeTag(mod) == .Optional)
20602 try Type.optional(sema.arena, dest_ptr_ty, mod)20620 try mod.optionalType(dest_ptr_ty.toIntern())
20603 else20621 else
20604 dest_ptr_ty;20622 dest_ptr_ty;
2060520623
...@@ -20617,11 +20635,7 @@ fn zirAddrSpaceCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst...@@ -20617,11 +20635,7 @@ fn zirAddrSpaceCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst
2061720635
20618fn resolveVaListRef(sema: *Sema, block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref) CompileError!Air.Inst.Ref {20636fn resolveVaListRef(sema: *Sema, block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref) CompileError!Air.Inst.Ref {
20619 const va_list_ty = try sema.getBuiltinType("VaList");20637 const va_list_ty = try sema.getBuiltinType("VaList");
20620 const va_list_ptr = try Type.ptr(sema.arena, sema.mod, .{20638 const va_list_ptr = try sema.mod.singleMutPtrType(va_list_ty);
20621 .pointee_type = va_list_ty,
20622 .mutable = true,
20623 .@"addrspace" = .generic,
20624 });
2062520639
20626 const inst = try sema.resolveInst(zir_ref);20640 const inst = try sema.resolveInst(zir_ref);
20627 return sema.coerce(block, va_list_ptr, inst, src);20641 return sema.coerce(block, va_list_ptr, inst, src);
...@@ -20698,20 +20712,22 @@ fn zirTypeName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -20698,20 +20712,22 @@ fn zirTypeName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
20698 var anon_decl = try block.startAnonDecl();20712 var anon_decl = try block.startAnonDecl();
20699 defer anon_decl.deinit();20713 defer anon_decl.deinit();
2070020714
20701 const bytes = try ty.nameAllocArena(sema.arena, mod);20715 var bytes = std.ArrayList(u8).init(sema.arena);
20716 defer bytes.deinit();
20717 try ty.print(bytes.writer(), mod);
2070220718
20703 const decl_ty = try mod.arrayType(.{20719 const decl_ty = try mod.arrayType(.{
20704 .len = bytes.len,20720 .len = bytes.items.len,
20705 .child = .u8_type,
20706 .sentinel = .zero_u8,20721 .sentinel = .zero_u8,
20722 .child = .u8_type,
20707 });20723 });
20708 const new_decl = try anon_decl.finish(20724 const new_decl = try anon_decl.finish(
20709 decl_ty,20725 decl_ty,
20710 (try mod.intern(.{ .aggregate = .{20726 (try mod.intern(.{ .aggregate = .{
20711 .ty = decl_ty.toIntern(),20727 .ty = decl_ty.toIntern(),
20712 .storage = .{ .bytes = bytes },20728 .storage = .{ .bytes = bytes.items },
20713 } })).toValue(),20729 } })).toValue(),
20714 0, // default alignment20730 .none, // default alignment
20715 );20731 );
2071620732
20717 return sema.analyzeDeclRef(new_decl);20733 return sema.analyzeDeclRef(new_decl);
...@@ -20962,7 +20978,7 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -20962,7 +20978,7 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
2096220978
20963 const operand_info = operand_ty.ptrInfo(mod);20979 const operand_info = operand_ty.ptrInfo(mod);
20964 const dest_info = dest_ty.ptrInfo(mod);20980 const dest_info = dest_ty.ptrInfo(mod);
20965 if (!operand_info.mutable and dest_info.mutable) {20981 if (operand_info.flags.is_const and !dest_info.flags.is_const) {
20966 const msg = msg: {20982 const msg = msg: {
20967 const msg = try sema.errMsg(block, src, "cast discards const qualifier", .{});20983 const msg = try sema.errMsg(block, src, "cast discards const qualifier", .{});
20968 errdefer msg.destroy(sema.gpa);20984 errdefer msg.destroy(sema.gpa);
...@@ -20972,7 +20988,7 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -20972,7 +20988,7 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
20972 };20988 };
20973 return sema.failWithOwnedErrorMsg(msg);20989 return sema.failWithOwnedErrorMsg(msg);
20974 }20990 }
20975 if (operand_info.@"volatile" and !dest_info.@"volatile") {20991 if (operand_info.flags.is_volatile and !dest_info.flags.is_volatile) {
20976 const msg = msg: {20992 const msg = msg: {
20977 const msg = try sema.errMsg(block, src, "cast discards volatile qualifier", .{});20993 const msg = try sema.errMsg(block, src, "cast discards volatile qualifier", .{});
20978 errdefer msg.destroy(sema.gpa);20994 errdefer msg.destroy(sema.gpa);
...@@ -20982,7 +20998,7 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -20982,7 +20998,7 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
20982 };20998 };
20983 return sema.failWithOwnedErrorMsg(msg);20999 return sema.failWithOwnedErrorMsg(msg);
20984 }21000 }
20985 if (operand_info.@"addrspace" != dest_info.@"addrspace") {21001 if (operand_info.flags.address_space != dest_info.flags.address_space) {
20986 const msg = msg: {21002 const msg = msg: {
20987 const msg = try sema.errMsg(block, src, "cast changes pointer address space", .{});21003 const msg = try sema.errMsg(block, src, "cast changes pointer address space", .{});
20988 errdefer msg.destroy(sema.gpa);21004 errdefer msg.destroy(sema.gpa);
...@@ -21014,14 +21030,12 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -21014,14 +21030,12 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
21014 // If the destination is less aligned than the source, preserve the source alignment21030 // If the destination is less aligned than the source, preserve the source alignment
21015 const aligned_dest_ty = if (operand_align <= dest_align) dest_ty else blk: {21031 const aligned_dest_ty = if (operand_align <= dest_align) dest_ty else blk: {
21016 // Unwrap the pointer (or pointer-like optional) type, set alignment, and re-wrap into result21032 // Unwrap the pointer (or pointer-like optional) type, set alignment, and re-wrap into result
21033 var dest_ptr_info = dest_ty.ptrInfo(mod);
21034 dest_ptr_info.flags.alignment = Alignment.fromNonzeroByteUnits(operand_align);
21017 if (dest_ty.zigTypeTag(mod) == .Optional) {21035 if (dest_ty.zigTypeTag(mod) == .Optional) {
21018 var dest_ptr_info = dest_ty.optionalChild(mod).ptrInfo(mod);21036 break :blk try mod.optionalType((try mod.ptrType(dest_ptr_info)).toIntern());
21019 dest_ptr_info.@"align" = operand_align;
21020 break :blk try Type.optional(sema.arena, try Type.ptr(sema.arena, mod, dest_ptr_info), mod);
21021 } else {21037 } else {
21022 var dest_ptr_info = dest_ty.ptrInfo(mod);21038 break :blk try mod.ptrType(dest_ptr_info);
21023 dest_ptr_info.@"align" = operand_align;
21024 break :blk try Type.ptr(sema.arena, mod, dest_ptr_info);
21025 }21039 }
21026 };21040 };
2102721041
...@@ -21088,8 +21102,8 @@ fn zirConstCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData...@@ -21088,8 +21102,8 @@ fn zirConstCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData
21088 try sema.checkPtrOperand(block, operand_src, operand_ty);21102 try sema.checkPtrOperand(block, operand_src, operand_ty);
2108921103
21090 var ptr_info = operand_ty.ptrInfo(mod);21104 var ptr_info = operand_ty.ptrInfo(mod);
21091 ptr_info.mutable = true;21105 ptr_info.flags.is_const = false;
21092 const dest_ty = try Type.ptr(sema.arena, mod, ptr_info);21106 const dest_ty = try mod.ptrType(ptr_info);
2109321107
21094 if (try sema.resolveMaybeUndefVal(operand)) |operand_val| {21108 if (try sema.resolveMaybeUndefVal(operand)) |operand_val| {
21095 return sema.addConstant(dest_ty, try mod.getCoerced(operand_val, dest_ty));21109 return sema.addConstant(dest_ty, try mod.getCoerced(operand_val, dest_ty));
...@@ -21109,8 +21123,8 @@ fn zirVolatileCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD...@@ -21109,8 +21123,8 @@ fn zirVolatileCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
21109 try sema.checkPtrOperand(block, operand_src, operand_ty);21123 try sema.checkPtrOperand(block, operand_src, operand_ty);
2111021124
21111 var ptr_info = operand_ty.ptrInfo(mod);21125 var ptr_info = operand_ty.ptrInfo(mod);
21112 ptr_info.@"volatile" = false;21126 ptr_info.flags.is_volatile = false;
21113 const dest_ty = try Type.ptr(sema.arena, mod, ptr_info);21127 const dest_ty = try mod.ptrType(ptr_info);
2111421128
21115 if (try sema.resolveMaybeUndefVal(operand)) |operand_val| {21129 if (try sema.resolveMaybeUndefVal(operand)) |operand_val| {
21116 return sema.addConstant(dest_ty, operand_val);21130 return sema.addConstant(dest_ty, operand_val);
...@@ -21219,28 +21233,29 @@ fn zirAlignCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -21219,28 +21233,29 @@ fn zirAlignCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
21219 try sema.checkPtrOperand(block, ptr_src, ptr_ty);21233 try sema.checkPtrOperand(block, ptr_src, ptr_ty);
2122021234
21221 var ptr_info = ptr_ty.ptrInfo(mod);21235 var ptr_info = ptr_ty.ptrInfo(mod);
21222 ptr_info.@"align" = dest_align;21236 ptr_info.flags.alignment = dest_align;
21223 var dest_ty = try Type.ptr(sema.arena, mod, ptr_info);21237 var dest_ty = try mod.ptrType(ptr_info);
21224 if (ptr_ty.zigTypeTag(mod) == .Optional) {21238 if (ptr_ty.zigTypeTag(mod) == .Optional) {
21225 dest_ty = try mod.optionalType(dest_ty.toIntern());21239 dest_ty = try mod.optionalType(dest_ty.toIntern());
21226 }21240 }
2122721241
21228 if (try sema.resolveDefinedValue(block, ptr_src, ptr)) |val| {21242 if (try sema.resolveDefinedValue(block, ptr_src, ptr)) |val| {
21229 if (try val.getUnsignedIntAdvanced(mod, null)) |addr| {21243 if (try val.getUnsignedIntAdvanced(mod, null)) |addr| {
21230 if (addr % dest_align != 0) {21244 const dest_align_bytes = dest_align.toByteUnitsOptional().?;
21231 return sema.fail(block, ptr_src, "pointer address 0x{X} is not aligned to {d} bytes", .{ addr, dest_align });21245 if (addr % dest_align_bytes != 0) {
21246 return sema.fail(block, ptr_src, "pointer address 0x{X} is not aligned to {d} bytes", .{ addr, dest_align_bytes });
21232 }21247 }
21233 }21248 }
21234 return sema.addConstant(dest_ty, try mod.getCoerced(val, dest_ty));21249 return sema.addConstant(dest_ty, try mod.getCoerced(val, dest_ty));
21235 }21250 }
2123621251
21237 try sema.requireRuntimeBlock(block, inst_data.src(), ptr_src);21252 try sema.requireRuntimeBlock(block, inst_data.src(), ptr_src);
21238 if (block.wantSafety() and dest_align > 1 and21253 if (block.wantSafety() and dest_align.order(Alignment.fromNonzeroByteUnits(1)).compare(.gt) and
21239 try sema.typeHasRuntimeBits(ptr_info.pointee_type))21254 try sema.typeHasRuntimeBits(ptr_info.child.toType()))
21240 {21255 {
21241 const align_minus_1 = try sema.addConstant(21256 const align_minus_1 = try sema.addConstant(
21242 Type.usize,21257 Type.usize,
21243 try mod.intValue(Type.usize, dest_align - 1),21258 try mod.intValue(Type.usize, dest_align.toByteUnitsOptional().? - 1),
21244 );21259 );
21245 const actual_ptr = if (ptr_ty.isSlice(mod))21260 const actual_ptr = if (ptr_ty.isSlice(mod))
21246 try sema.analyzeSlicePtr(block, ptr_src, ptr, ptr_ty)21261 try sema.analyzeSlicePtr(block, ptr_src, ptr, ptr_ty)
...@@ -21685,28 +21700,29 @@ fn checkAtomicPtrOperand(...@@ -21685,28 +21700,29 @@ fn checkAtomicPtrOperand(
21685 ),21700 ),
21686 };21701 };
2168721702
21688 var wanted_ptr_data: Type.Payload.Pointer.Data = .{21703 var wanted_ptr_data: InternPool.Key.PtrType = .{
21689 .pointee_type = elem_ty,21704 .child = elem_ty.toIntern(),
21690 .@"align" = alignment,21705 .flags = .{
21691 .@"addrspace" = .generic,21706 .alignment = alignment,
21692 .mutable = !ptr_const,21707 .is_const = ptr_const,
21708 },
21693 };21709 };
2169421710
21695 const ptr_ty = sema.typeOf(ptr);21711 const ptr_ty = sema.typeOf(ptr);
21696 const ptr_data = switch (try ptr_ty.zigTypeTagOrPoison(mod)) {21712 const ptr_data = switch (try ptr_ty.zigTypeTagOrPoison(mod)) {
21697 .Pointer => ptr_ty.ptrInfo(mod),21713 .Pointer => ptr_ty.ptrInfo(mod),
21698 else => {21714 else => {
21699 const wanted_ptr_ty = try Type.ptr(sema.arena, mod, wanted_ptr_data);21715 const wanted_ptr_ty = try mod.ptrType(wanted_ptr_data);
21700 _ = try sema.coerce(block, wanted_ptr_ty, ptr, ptr_src);21716 _ = try sema.coerce(block, wanted_ptr_ty, ptr, ptr_src);
21701 unreachable;21717 unreachable;
21702 },21718 },
21703 };21719 };
2170421720
21705 wanted_ptr_data.@"addrspace" = ptr_data.@"addrspace";21721 wanted_ptr_data.flags.address_space = ptr_data.flags.address_space;
21706 wanted_ptr_data.@"allowzero" = ptr_data.@"allowzero";21722 wanted_ptr_data.flags.is_allowzero = ptr_data.flags.is_allowzero;
21707 wanted_ptr_data.@"volatile" = ptr_data.@"volatile";21723 wanted_ptr_data.flags.is_volatile = ptr_data.flags.is_volatile;
2170821724
21709 const wanted_ptr_ty = try Type.ptr(sema.arena, mod, wanted_ptr_data);21725 const wanted_ptr_ty = try mod.ptrType(wanted_ptr_data);
21710 const casted_ptr = try sema.coerce(block, wanted_ptr_ty, ptr, ptr_src);21726 const casted_ptr = try sema.coerce(block, wanted_ptr_ty, ptr, ptr_src);
2171121727
21712 return casted_ptr;21728 return casted_ptr;
...@@ -22059,7 +22075,7 @@ fn zirCmpxchg(...@@ -22059,7 +22075,7 @@ fn zirCmpxchg(
22059 return sema.fail(block, failure_order_src, "failure atomic ordering must not be Release or AcqRel", .{});22075 return sema.fail(block, failure_order_src, "failure atomic ordering must not be Release or AcqRel", .{});
22060 }22076 }
2206122077
22062 const result_ty = try Type.optional(sema.arena, elem_ty, mod);22078 const result_ty = try mod.optionalType(elem_ty.toIntern());
2206322079
22064 // special case zero bit types22080 // special case zero bit types
22065 if ((try sema.typeHasOnePossibleValue(elem_ty)) != null) {22081 if ((try sema.typeHasOnePossibleValue(elem_ty)) != null) {
...@@ -22825,31 +22841,33 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -22825,31 +22841,33 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
22825 try sema.checkPtrOperand(block, ptr_src, field_ptr_ty);22841 try sema.checkPtrOperand(block, ptr_src, field_ptr_ty);
22826 const field_ptr_ty_info = field_ptr_ty.ptrInfo(mod);22842 const field_ptr_ty_info = field_ptr_ty.ptrInfo(mod);
2282722843
22828 var ptr_ty_data: Type.Payload.Pointer.Data = .{22844 var ptr_ty_data: InternPool.Key.PtrType = .{
22829 .pointee_type = parent_ty.structFieldType(field_index, mod),22845 .child = parent_ty.structFieldType(field_index, mod).toIntern(),
22830 .mutable = field_ptr_ty_info.mutable,22846 .flags = .{
22831 .@"addrspace" = field_ptr_ty_info.@"addrspace",22847 .address_space = field_ptr_ty_info.flags.address_space,
22848 .is_const = field_ptr_ty_info.flags.is_const,
22849 },
22832 };22850 };
2283322851
22834 if (parent_ty.containerLayout(mod) == .Packed) {22852 if (parent_ty.containerLayout(mod) == .Packed) {
22835 return sema.fail(block, src, "TODO handle packed structs/unions with @fieldParentPtr", .{});22853 return sema.fail(block, src, "TODO handle packed structs/unions with @fieldParentPtr", .{});
22836 } else {22854 } else {
22837 ptr_ty_data.@"align" = blk: {22855 ptr_ty_data.flags.alignment = blk: {
22838 if (mod.typeToStruct(parent_ty)) |struct_obj| {22856 if (mod.typeToStruct(parent_ty)) |struct_obj| {
22839 break :blk struct_obj.fields.values()[field_index].abi_align;22857 break :blk struct_obj.fields.values()[field_index].abi_align;
22840 } else if (mod.typeToUnion(parent_ty)) |union_obj| {22858 } else if (mod.typeToUnion(parent_ty)) |union_obj| {
22841 break :blk union_obj.fields.values()[field_index].abi_align;22859 break :blk union_obj.fields.values()[field_index].abi_align;
22842 } else {22860 } else {
22843 break :blk 0;22861 break :blk .none;
22844 }22862 }
22845 };22863 };
22846 }22864 }
2284722865
22848 const actual_field_ptr_ty = try Type.ptr(sema.arena, sema.mod, ptr_ty_data);22866 const actual_field_ptr_ty = try mod.ptrType(ptr_ty_data);
22849 const casted_field_ptr = try sema.coerce(block, actual_field_ptr_ty, field_ptr, ptr_src);22867 const casted_field_ptr = try sema.coerce(block, actual_field_ptr_ty, field_ptr, ptr_src);
2285022868
22851 ptr_ty_data.pointee_type = parent_ty;22869 ptr_ty_data.child = parent_ty.toIntern();
22852 const result_ptr = try Type.ptr(sema.arena, sema.mod, ptr_ty_data);22870 const result_ptr = try mod.ptrType(ptr_ty_data);
2285322871
22854 if (try sema.resolveDefinedValue(block, src, casted_field_ptr)) |field_ptr_val| {22872 if (try sema.resolveDefinedValue(block, src, casted_field_ptr)) |field_ptr_val| {
22855 const field = switch (ip.indexToKey(field_ptr_val.toIntern())) {22873 const field = switch (ip.indexToKey(field_ptr_val.toIntern())) {
...@@ -23172,21 +23190,25 @@ fn analyzeMinMax(...@@ -23172,21 +23190,25 @@ fn analyzeMinMax(
23172fn upgradeToArrayPtr(sema: *Sema, block: *Block, ptr: Air.Inst.Ref, len: u64) !Air.Inst.Ref {23190fn upgradeToArrayPtr(sema: *Sema, block: *Block, ptr: Air.Inst.Ref, len: u64) !Air.Inst.Ref {
23173 const mod = sema.mod;23191 const mod = sema.mod;
23174 const info = sema.typeOf(ptr).ptrInfo(mod);23192 const info = sema.typeOf(ptr).ptrInfo(mod);
23175 if (info.size == .One) {23193 if (info.flags.size == .One) {
23176 // Already an array pointer.23194 // Already an array pointer.
23177 return ptr;23195 return ptr;
23178 }23196 }
23179 const new_ty = try Type.ptr(sema.arena, mod, .{23197 const new_ty = try mod.ptrType(.{
23180 .pointee_type = try Type.array(sema.arena, len, info.sentinel, info.pointee_type, mod),23198 .child = (try mod.arrayType(.{
23181 .sentinel = null,23199 .len = len,
23182 .@"align" = info.@"align",23200 .sentinel = info.sentinel,
23183 .@"addrspace" = info.@"addrspace",23201 .child = info.child,
23184 .mutable = info.mutable,23202 })).toIntern(),
23185 .@"allowzero" = info.@"allowzero",23203 .flags = .{
23186 .@"volatile" = info.@"volatile",23204 .alignment = info.flags.alignment,
23187 .size = .One,23205 .is_const = info.flags.is_const,
23206 .is_volatile = info.flags.is_volatile,
23207 .is_allowzero = info.flags.is_allowzero,
23208 .address_space = info.flags.address_space,
23209 },
23188 });23210 });
23189 if (info.size == .Slice) {23211 if (info.flags.size == .Slice) {
23190 return block.addTyOp(.slice_ptr, new_ty, ptr);23212 return block.addTyOp(.slice_ptr, new_ty, ptr);
23191 }23213 }
23192 return block.addBitCast(new_ty, ptr);23214 return block.addBitCast(new_ty, ptr);
...@@ -23604,7 +23626,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -23604,7 +23626,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
23604 return sema.fail(block, align_src, "target does not support function alignment", .{});23626 return sema.fail(block, align_src, "target does not support function alignment", .{});
23605 }23627 }
2360623628
23607 const @"align": ?u32 = if (extra.data.bits.has_align_body) blk: {23629 const @"align": ?Alignment = if (extra.data.bits.has_align_body) blk: {
23608 const body_len = sema.code.extra[extra_index];23630 const body_len = sema.code.extra[extra_index];
23609 extra_index += 1;23631 extra_index += 1;
23610 const body = sema.code.extra[extra_index..][0..body_len];23632 const body = sema.code.extra[extra_index..][0..body_len];
...@@ -23617,9 +23639,9 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -23617,9 +23639,9 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
23617 const alignment = @intCast(u32, val.toUnsignedInt(mod));23639 const alignment = @intCast(u32, val.toUnsignedInt(mod));
23618 try sema.validateAlign(block, align_src, alignment);23640 try sema.validateAlign(block, align_src, alignment);
23619 if (alignment == target_util.defaultFunctionAlignment(target)) {23641 if (alignment == target_util.defaultFunctionAlignment(target)) {
23620 break :blk 0;23642 break :blk .none;
23621 } else {23643 } else {
23622 break :blk alignment;23644 break :blk Alignment.fromNonzeroByteUnits(alignment);
23623 }23645 }
23624 } else if (extra.data.bits.has_align_ref) blk: {23646 } else if (extra.data.bits.has_align_ref) blk: {
23625 const align_ref = @enumFromInt(Zir.Inst.Ref, sema.code.extra[extra_index]);23647 const align_ref = @enumFromInt(Zir.Inst.Ref, sema.code.extra[extra_index]);
...@@ -23633,11 +23655,11 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -23633,11 +23655,11 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
23633 const alignment = @intCast(u32, align_tv.val.toUnsignedInt(mod));23655 const alignment = @intCast(u32, align_tv.val.toUnsignedInt(mod));
23634 try sema.validateAlign(block, align_src, alignment);23656 try sema.validateAlign(block, align_src, alignment);
23635 if (alignment == target_util.defaultFunctionAlignment(target)) {23657 if (alignment == target_util.defaultFunctionAlignment(target)) {
23636 break :blk 0;23658 break :blk .none;
23637 } else {23659 } else {
23638 break :blk alignment;23660 break :blk Alignment.fromNonzeroByteUnits(alignment);
23639 }23661 }
23640 } else 0;23662 } else .none;
2364123663
23642 const @"addrspace": ?std.builtin.AddressSpace = if (extra.data.bits.has_addrspace_body) blk: {23664 const @"addrspace": ?std.builtin.AddressSpace = if (extra.data.bits.has_addrspace_body) blk: {
23643 const body_len = sema.code.extra[extra_index];23665 const body_len = sema.code.extra[extra_index];
...@@ -24032,7 +24054,7 @@ fn zirBuiltinExtern(...@@ -24032,7 +24054,7 @@ fn zirBuiltinExtern(
24032 };24054 };
2403324055
24034 if (options.linkage == .Weak and !ty.ptrAllowsZero(mod)) {24056 if (options.linkage == .Weak and !ty.ptrAllowsZero(mod)) {
24035 ty = try Type.optional(sema.arena, ty, mod);24057 ty = try mod.optionalType(ty.toIntern());
24036 }24058 }
2403724059
24038 // TODO check duplicate extern24060 // TODO check duplicate extern
...@@ -24058,7 +24080,7 @@ fn zirBuiltinExtern(...@@ -24058,7 +24080,7 @@ fn zirBuiltinExtern(
24058 // below, so this type doesn't matter24080 // below, so this type doesn't matter
24059 new_decl.ty = ty;24081 new_decl.ty = ty;
24060 new_decl.val = new_var.toValue();24082 new_decl.val = new_var.toValue();
24061 new_decl.@"align" = 0;24083 new_decl.alignment = .none;
24062 new_decl.@"linksection" = .none;24084 new_decl.@"linksection" = .none;
24063 new_decl.has_tv = true;24085 new_decl.has_tv = true;
24064 new_decl.analysis = .complete;24086 new_decl.analysis = .complete;
...@@ -24948,18 +24970,19 @@ fn fieldVal(...@@ -24948,18 +24970,19 @@ fn fieldVal(
24948 );24970 );
24949 } else if (ip.stringEqlSlice(field_name, "ptr") and is_pointer_to) {24971 } else if (ip.stringEqlSlice(field_name, "ptr") and is_pointer_to) {
24950 const ptr_info = object_ty.ptrInfo(mod);24972 const ptr_info = object_ty.ptrInfo(mod);
24951 const result_ty = try Type.ptr(sema.arena, mod, .{24973 const result_ty = try mod.ptrType(.{
24952 .pointee_type = ptr_info.pointee_type.childType(mod),24974 .child = ptr_info.child.toType().childType(mod).toIntern(),
24953 .sentinel = ptr_info.sentinel,24975 .sentinel = ptr_info.sentinel,
24954 .@"align" = ptr_info.@"align",24976 .flags = .{
24955 .@"addrspace" = ptr_info.@"addrspace",24977 .size = .Many,
24956 .bit_offset = ptr_info.bit_offset,24978 .alignment = ptr_info.flags.alignment,
24957 .host_size = ptr_info.host_size,24979 .is_const = ptr_info.flags.is_const,
24958 .vector_index = ptr_info.vector_index,24980 .is_volatile = ptr_info.flags.is_volatile,
24959 .@"allowzero" = ptr_info.@"allowzero",24981 .is_allowzero = ptr_info.flags.is_allowzero,
24960 .mutable = ptr_info.mutable,24982 .address_space = ptr_info.flags.address_space,
24961 .@"volatile" = ptr_info.@"volatile",24983 .vector_index = ptr_info.flags.vector_index,
24962 .size = .Many,24984 },
24985 .packed_offset = ptr_info.packed_offset,
24963 });24986 });
24964 return sema.coerce(block, result_ty, object, src);24987 return sema.coerce(block, result_ty, object, src);
24965 } else {24988 } else {
...@@ -24973,7 +24996,7 @@ fn fieldVal(...@@ -24973,7 +24996,7 @@ fn fieldVal(
24973 },24996 },
24974 .Pointer => {24997 .Pointer => {
24975 const ptr_info = inner_ty.ptrInfo(mod);24998 const ptr_info = inner_ty.ptrInfo(mod);
24976 if (ptr_info.size == .Slice) {24999 if (ptr_info.flags.size == .Slice) {
24977 if (ip.stringEqlSlice(field_name, "ptr")) {25000 if (ip.stringEqlSlice(field_name, "ptr")) {
24978 const slice = if (is_pointer_to)25001 const slice = if (is_pointer_to)
24979 try sema.analyzeLoad(block, src, object, object_src)25002 try sema.analyzeLoad(block, src, object, object_src)
...@@ -25147,7 +25170,7 @@ fn fieldPtr(...@@ -25147,7 +25170,7 @@ fn fieldPtr(
25147 return sema.analyzeDeclRef(try anon_decl.finish(25170 return sema.analyzeDeclRef(try anon_decl.finish(
25148 Type.usize,25171 Type.usize,
25149 try mod.intValue(Type.usize, inner_ty.arrayLen(mod)),25172 try mod.intValue(Type.usize, inner_ty.arrayLen(mod)),
25150 0, // default alignment25173 .none, // default alignment
25151 ));25174 ));
25152 } else {25175 } else {
25153 return sema.fail(25176 return sema.fail(
...@@ -25169,11 +25192,13 @@ fn fieldPtr(...@@ -25169,11 +25192,13 @@ fn fieldPtr(
25169 if (ip.stringEqlSlice(field_name, "ptr")) {25192 if (ip.stringEqlSlice(field_name, "ptr")) {
25170 const slice_ptr_ty = inner_ty.slicePtrFieldType(mod);25193 const slice_ptr_ty = inner_ty.slicePtrFieldType(mod);
2517125194
25172 const result_ty = try Type.ptr(sema.arena, mod, .{25195 const result_ty = try mod.ptrType(.{
25173 .pointee_type = slice_ptr_ty,25196 .child = slice_ptr_ty.toIntern(),
25174 .mutable = attr_ptr_ty.ptrIsMutable(mod),25197 .flags = .{
25175 .@"volatile" = attr_ptr_ty.isVolatilePtr(mod),25198 .is_const = !attr_ptr_ty.ptrIsMutable(mod),
25176 .@"addrspace" = attr_ptr_ty.ptrAddressSpace(mod),25199 .is_volatile = attr_ptr_ty.isVolatilePtr(mod),
25200 .address_space = attr_ptr_ty.ptrAddressSpace(mod),
25201 },
25177 });25202 });
2517825203
25179 if (try sema.resolveDefinedValue(block, object_ptr_src, inner_ptr)) |val| {25204 if (try sema.resolveDefinedValue(block, object_ptr_src, inner_ptr)) |val| {
...@@ -25189,11 +25214,13 @@ fn fieldPtr(...@@ -25189,11 +25214,13 @@ fn fieldPtr(
2518925214
25190 return block.addTyOp(.ptr_slice_ptr_ptr, result_ty, inner_ptr);25215 return block.addTyOp(.ptr_slice_ptr_ptr, result_ty, inner_ptr);
25191 } else if (ip.stringEqlSlice(field_name, "len")) {25216 } else if (ip.stringEqlSlice(field_name, "len")) {
25192 const result_ty = try Type.ptr(sema.arena, mod, .{25217 const result_ty = try mod.ptrType(.{
25193 .pointee_type = Type.usize,25218 .child = .usize_type,
25194 .mutable = attr_ptr_ty.ptrIsMutable(mod),25219 .flags = .{
25195 .@"volatile" = attr_ptr_ty.isVolatilePtr(mod),25220 .is_const = !attr_ptr_ty.ptrIsMutable(mod),
25196 .@"addrspace" = attr_ptr_ty.ptrAddressSpace(mod),25221 .is_volatile = attr_ptr_ty.isVolatilePtr(mod),
25222 .address_space = attr_ptr_ty.ptrAddressSpace(mod),
25223 },
25197 });25224 });
2519825225
25199 if (try sema.resolveDefinedValue(block, object_ptr_src, inner_ptr)) |val| {25226 if (try sema.resolveDefinedValue(block, object_ptr_src, inner_ptr)) |val| {
...@@ -25261,7 +25288,7 @@ fn fieldPtr(...@@ -25261,7 +25288,7 @@ fn fieldPtr(
25261 .ty = error_set_type.toIntern(),25288 .ty = error_set_type.toIntern(),
25262 .name = field_name,25289 .name = field_name,
25263 } })).toValue(),25290 } })).toValue(),
25264 0, // default alignment25291 .none, // default alignment
25265 ));25292 ));
25266 },25293 },
25267 .Union => {25294 .Union => {
...@@ -25279,7 +25306,7 @@ fn fieldPtr(...@@ -25279,7 +25306,7 @@ fn fieldPtr(
25279 return sema.analyzeDeclRef(try anon_decl.finish(25306 return sema.analyzeDeclRef(try anon_decl.finish(
25280 enum_ty,25307 enum_ty,
25281 try mod.enumValueFieldIndex(enum_ty, field_index_u32),25308 try mod.enumValueFieldIndex(enum_ty, field_index_u32),
25282 0, // default alignment25309 .none, // default alignment
25283 ));25310 ));
25284 }25311 }
25285 }25312 }
...@@ -25300,7 +25327,7 @@ fn fieldPtr(...@@ -25300,7 +25327,7 @@ fn fieldPtr(
25300 return sema.analyzeDeclRef(try anon_decl.finish(25327 return sema.analyzeDeclRef(try anon_decl.finish(
25301 child_type,25328 child_type,
25302 try mod.enumValueFieldIndex(child_type, field_index_u32),25329 try mod.enumValueFieldIndex(child_type, field_index_u32),
25303 0, // default alignment25330 .none, // default alignment
25304 ));25331 ));
25305 },25332 },
25306 .Struct, .Opaque => {25333 .Struct, .Opaque => {
...@@ -25514,11 +25541,12 @@ fn finishFieldCallBind(...@@ -25514,11 +25541,12 @@ fn finishFieldCallBind(
25514 object_ptr: Air.Inst.Ref,25541 object_ptr: Air.Inst.Ref,
25515) CompileError!ResolvedFieldCallee {25542) CompileError!ResolvedFieldCallee {
25516 const mod = sema.mod;25543 const mod = sema.mod;
25517 const arena = sema.arena;25544 const ptr_field_ty = try mod.ptrType(.{
25518 const ptr_field_ty = try Type.ptr(arena, mod, .{25545 .child = field_ty.toIntern(),
25519 .pointee_type = field_ty,25546 .flags = .{
25520 .mutable = ptr_ty.ptrIsMutable(mod),25547 .is_const = !ptr_ty.ptrIsMutable(mod),
25521 .@"addrspace" = ptr_ty.ptrAddressSpace(mod),25548 .address_space = ptr_ty.ptrAddressSpace(mod),
25549 },
25522 });25550 });
2552325551
25524 const container_ty = ptr_ty.childType(mod);25552 const container_ty = ptr_ty.childType(mod);
...@@ -25651,11 +25679,13 @@ fn structFieldPtrByIndex(...@@ -25651,11 +25679,13 @@ fn structFieldPtrByIndex(
25651 const struct_ptr_ty = sema.typeOf(struct_ptr);25679 const struct_ptr_ty = sema.typeOf(struct_ptr);
25652 const struct_ptr_ty_info = struct_ptr_ty.ptrInfo(mod);25680 const struct_ptr_ty_info = struct_ptr_ty.ptrInfo(mod);
2565325681
25654 var ptr_ty_data: Type.Payload.Pointer.Data = .{25682 var ptr_ty_data: InternPool.Key.PtrType = .{
25655 .pointee_type = field.ty,25683 .child = field.ty.toIntern(),
25656 .mutable = struct_ptr_ty_info.mutable,25684 .flags = .{
25657 .@"volatile" = struct_ptr_ty_info.@"volatile",25685 .is_const = struct_ptr_ty_info.flags.is_const,
25658 .@"addrspace" = struct_ptr_ty_info.@"addrspace",25686 .is_volatile = struct_ptr_ty_info.flags.is_volatile,
25687 .address_space = struct_ptr_ty_info.flags.address_space,
25688 },
25659 };25689 };
2566025690
25661 const target = mod.getTarget();25691 const target = mod.getTarget();
...@@ -25668,24 +25698,22 @@ fn structFieldPtrByIndex(...@@ -25668,24 +25698,22 @@ fn structFieldPtrByIndex(
25668 if (!(try sema.typeHasRuntimeBits(f.ty))) continue;25698 if (!(try sema.typeHasRuntimeBits(f.ty))) continue;
2566925699
25670 if (i == field_index) {25700 if (i == field_index) {
25671 ptr_ty_data.bit_offset = running_bits;25701 ptr_ty_data.packed_offset.bit_offset = running_bits;
25672 }25702 }
25673 running_bits += @intCast(u16, f.ty.bitSize(mod));25703 running_bits += @intCast(u16, f.ty.bitSize(mod));
25674 }25704 }
25675 ptr_ty_data.host_size = (running_bits + 7) / 8;25705 ptr_ty_data.packed_offset.host_size = (running_bits + 7) / 8;
2567625706
25677 // If this is a packed struct embedded in another one, we need to offset25707 // If this is a packed struct embedded in another one, we need to offset
25678 // the bits against each other.25708 // the bits against each other.
25679 if (struct_ptr_ty_info.host_size != 0) {25709 if (struct_ptr_ty_info.packed_offset.host_size != 0) {
25680 ptr_ty_data.host_size = struct_ptr_ty_info.host_size;25710 ptr_ty_data.packed_offset.host_size = struct_ptr_ty_info.packed_offset.host_size;
25681 ptr_ty_data.bit_offset += struct_ptr_ty_info.bit_offset;25711 ptr_ty_data.packed_offset.bit_offset += struct_ptr_ty_info.packed_offset.bit_offset;
25682 }25712 }
2568325713
25684 const parent_align = if (struct_ptr_ty_info.@"align" != 0)25714 const parent_align = struct_ptr_ty_info.flags.alignment.toByteUnitsOptional() orelse
25685 struct_ptr_ty_info.@"align"25715 struct_ptr_ty_info.child.toType().abiAlignment(mod);
25686 else25716 ptr_ty_data.flags.alignment = Alignment.fromByteUnits(parent_align);
25687 struct_ptr_ty_info.pointee_type.abiAlignment(mod);
25688 ptr_ty_data.@"align" = parent_align;
2568925717
25690 // If the field happens to be byte-aligned, simplify the pointer type.25718 // If the field happens to be byte-aligned, simplify the pointer type.
25691 // The pointee type bit size must match its ABI byte size so that loads and stores25719 // The pointee type bit size must match its ABI byte size so that loads and stores
...@@ -25695,24 +25723,24 @@ fn structFieldPtrByIndex(...@@ -25695,24 +25723,24 @@ fn structFieldPtrByIndex(
25695 // targets before adding the necessary complications to this code. This will not25723 // targets before adding the necessary complications to this code. This will not
25696 // cause miscompilations; it only means the field pointer uses bit masking when it25724 // cause miscompilations; it only means the field pointer uses bit masking when it
25697 // might not be strictly necessary.25725 // might not be strictly necessary.
25698 if (parent_align != 0 and ptr_ty_data.bit_offset % 8 == 0 and25726 if (parent_align != 0 and ptr_ty_data.packed_offset.bit_offset % 8 == 0 and
25699 target.cpu.arch.endian() == .Little)25727 target.cpu.arch.endian() == .Little)
25700 {25728 {
25701 const elem_size_bytes = ptr_ty_data.pointee_type.abiSize(mod);25729 const elem_size_bytes = ptr_ty_data.child.toType().abiSize(mod);
25702 const elem_size_bits = ptr_ty_data.pointee_type.bitSize(mod);25730 const elem_size_bits = ptr_ty_data.child.toType().bitSize(mod);
25703 if (elem_size_bytes * 8 == elem_size_bits) {25731 if (elem_size_bytes * 8 == elem_size_bits) {
25704 const byte_offset = ptr_ty_data.bit_offset / 8;25732 const byte_offset = ptr_ty_data.packed_offset.bit_offset / 8;
25705 const new_align = @as(u32, 1) << @intCast(u5, @ctz(byte_offset | parent_align));25733 const new_align = @enumFromInt(Alignment, @ctz(byte_offset | parent_align));
25706 ptr_ty_data.bit_offset = 0;25734 assert(new_align != .none);
25707 ptr_ty_data.host_size = 0;25735 ptr_ty_data.flags.alignment = new_align;
25708 ptr_ty_data.@"align" = new_align;25736 ptr_ty_data.packed_offset = .{ .host_size = 0, .bit_offset = 0 };
25709 }25737 }
25710 }25738 }
25711 } else {25739 } else {
25712 ptr_ty_data.@"align" = field.abi_align;25740 ptr_ty_data.flags.alignment = field.abi_align;
25713 }25741 }
2571425742
25715 const ptr_field_ty = try Type.ptr(sema.arena, mod, ptr_ty_data);25743 const ptr_field_ty = try mod.ptrType(ptr_ty_data);
2571625744
25717 if (field.is_comptime) {25745 if (field.is_comptime) {
25718 const val = try mod.intern(.{ .ptr = .{25746 const val = try mod.intern(.{ .ptr = .{
...@@ -25874,7 +25902,6 @@ fn unionFieldPtr(...@@ -25874,7 +25902,6 @@ fn unionFieldPtr(
25874 unresolved_union_ty: Type,25902 unresolved_union_ty: Type,
25875 initializing: bool,25903 initializing: bool,
25876) CompileError!Air.Inst.Ref {25904) CompileError!Air.Inst.Ref {
25877 const arena = sema.arena;
25878 const mod = sema.mod;25905 const mod = sema.mod;
25879 const ip = &mod.intern_pool;25906 const ip = &mod.intern_pool;
2588025907
...@@ -25885,11 +25912,13 @@ fn unionFieldPtr(...@@ -25885,11 +25912,13 @@ fn unionFieldPtr(
25885 const union_obj = mod.typeToUnion(union_ty).?;25912 const union_obj = mod.typeToUnion(union_ty).?;
25886 const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_name_src);25913 const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_name_src);
25887 const field = union_obj.fields.values()[field_index];25914 const field = union_obj.fields.values()[field_index];
25888 const ptr_field_ty = try Type.ptr(arena, mod, .{25915 const ptr_field_ty = try mod.ptrType(.{
25889 .pointee_type = field.ty,25916 .child = field.ty.toIntern(),
25890 .mutable = union_ptr_ty.ptrIsMutable(mod),25917 .flags = .{
25891 .@"volatile" = union_ptr_ty.isVolatilePtr(mod),25918 .is_const = !union_ptr_ty.ptrIsMutable(mod),
25892 .@"addrspace" = union_ptr_ty.ptrAddressSpace(mod),25919 .is_volatile = union_ptr_ty.isVolatilePtr(mod),
25920 .address_space = union_ptr_ty.ptrAddressSpace(mod),
25921 },
25893 });25922 });
25894 const enum_field_index = @intCast(u32, union_obj.tag_ty.enumFieldIndex(field_name, mod).?);25923 const enum_field_index = @intCast(u32, union_obj.tag_ty.enumFieldIndex(field_name, mod).?);
2589525924
...@@ -26250,11 +26279,13 @@ fn tupleFieldPtr(...@@ -26250,11 +26279,13 @@ fn tupleFieldPtr(
26250 }26279 }
2625126280
26252 const field_ty = tuple_ty.structFieldType(field_index, mod);26281 const field_ty = tuple_ty.structFieldType(field_index, mod);
26253 const ptr_field_ty = try Type.ptr(sema.arena, mod, .{26282 const ptr_field_ty = try mod.ptrType(.{
26254 .pointee_type = field_ty,26283 .child = field_ty.toIntern(),
26255 .mutable = tuple_ptr_ty.ptrIsMutable(mod),26284 .flags = .{
26256 .@"volatile" = tuple_ptr_ty.isVolatilePtr(mod),26285 .is_const = !tuple_ptr_ty.ptrIsMutable(mod),
26257 .@"addrspace" = tuple_ptr_ty.ptrAddressSpace(mod),26286 .is_volatile = tuple_ptr_ty.isVolatilePtr(mod),
26287 .address_space = tuple_ptr_ty.ptrAddressSpace(mod),
26288 },
26258 });26289 });
2625926290
26260 if (try tuple_ty.structFieldValueComptime(mod, field_index)) |default_val| {26291 if (try tuple_ty.structFieldValueComptime(mod, field_index)) |default_val| {
...@@ -26705,15 +26736,15 @@ fn coerceExtra(...@@ -26705,15 +26736,15 @@ fn coerceExtra(
2670526736
26706 // *T to *[1]T26737 // *T to *[1]T
26707 single_item: {26738 single_item: {
26708 if (dest_info.size != .One) break :single_item;26739 if (dest_info.flags.size != .One) break :single_item;
26709 if (!inst_ty.isSinglePointer(mod)) break :single_item;26740 if (!inst_ty.isSinglePointer(mod)) break :single_item;
26710 if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :pointer;26741 if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :pointer;
26711 const ptr_elem_ty = inst_ty.childType(mod);26742 const ptr_elem_ty = inst_ty.childType(mod);
26712 const array_ty = dest_info.pointee_type;26743 const array_ty = dest_info.child.toType();
26713 if (array_ty.zigTypeTag(mod) != .Array) break :single_item;26744 if (array_ty.zigTypeTag(mod) != .Array) break :single_item;
26714 const array_elem_ty = array_ty.childType(mod);26745 const array_elem_ty = array_ty.childType(mod);
26715 if (array_ty.arrayLen(mod) != 1) break :single_item;26746 if (array_ty.arrayLen(mod) != 1) break :single_item;
26716 const dest_is_mut = dest_info.mutable;26747 const dest_is_mut = !dest_info.flags.is_const;
26717 switch (try sema.coerceInMemoryAllowed(block, array_elem_ty, ptr_elem_ty, dest_is_mut, target, dest_ty_src, inst_src)) {26748 switch (try sema.coerceInMemoryAllowed(block, array_elem_ty, ptr_elem_ty, dest_is_mut, target, dest_ty_src, inst_src)) {
26718 .ok => {},26749 .ok => {},
26719 else => break :single_item,26750 else => break :single_item,
...@@ -26728,9 +26759,9 @@ fn coerceExtra(...@@ -26728,9 +26759,9 @@ fn coerceExtra(
26728 const array_ty = inst_ty.childType(mod);26759 const array_ty = inst_ty.childType(mod);
26729 if (array_ty.zigTypeTag(mod) != .Array) break :src_array_ptr;26760 if (array_ty.zigTypeTag(mod) != .Array) break :src_array_ptr;
26730 const array_elem_type = array_ty.childType(mod);26761 const array_elem_type = array_ty.childType(mod);
26731 const dest_is_mut = dest_info.mutable;26762 const dest_is_mut = !dest_info.flags.is_const;
2673226763
26733 const dst_elem_type = dest_info.pointee_type;26764 const dst_elem_type = dest_info.child.toType();
26734 const elem_res = try sema.coerceInMemoryAllowed(block, dst_elem_type, array_elem_type, dest_is_mut, target, dest_ty_src, inst_src);26765 const elem_res = try sema.coerceInMemoryAllowed(block, dst_elem_type, array_elem_type, dest_is_mut, target, dest_ty_src, inst_src);
26735 switch (elem_res) {26766 switch (elem_res) {
26736 .ok => {},26767 .ok => {},
...@@ -26744,12 +26775,12 @@ fn coerceExtra(...@@ -26744,12 +26775,12 @@ fn coerceExtra(
26744 },26775 },
26745 }26776 }
2674626777
26747 if (dest_info.sentinel) |dest_sent| {26778 if (dest_info.sentinel != .none) {
26748 if (array_ty.sentinel(mod)) |inst_sent| {26779 if (array_ty.sentinel(mod)) |inst_sent| {
26749 if (!dest_sent.eql(inst_sent, dst_elem_type, mod)) {26780 if (dest_info.sentinel != (try mod.getCoerced(inst_sent, dst_elem_type)).toIntern()) {
26750 in_memory_result = .{ .ptr_sentinel = .{26781 in_memory_result = .{ .ptr_sentinel = .{
26751 .actual = inst_sent,26782 .actual = inst_sent,
26752 .wanted = dest_sent,26783 .wanted = dest_info.sentinel.toValue(),
26753 .ty = dst_elem_type,26784 .ty = dst_elem_type,
26754 } };26785 } };
26755 break :src_array_ptr;26786 break :src_array_ptr;
...@@ -26757,14 +26788,14 @@ fn coerceExtra(...@@ -26757,14 +26788,14 @@ fn coerceExtra(
26757 } else {26788 } else {
26758 in_memory_result = .{ .ptr_sentinel = .{26789 in_memory_result = .{ .ptr_sentinel = .{
26759 .actual = Value.@"unreachable",26790 .actual = Value.@"unreachable",
26760 .wanted = dest_sent,26791 .wanted = dest_info.sentinel.toValue(),
26761 .ty = dst_elem_type,26792 .ty = dst_elem_type,
26762 } };26793 } };
26763 break :src_array_ptr;26794 break :src_array_ptr;
26764 }26795 }
26765 }26796 }
2676626797
26767 switch (dest_info.size) {26798 switch (dest_info.flags.size) {
26768 .Slice => {26799 .Slice => {
26769 // *[N]T to []T26800 // *[N]T to []T
26770 return sema.coerceArrayPtrToSlice(block, dest_ty, inst, inst_src);26801 return sema.coerceArrayPtrToSlice(block, dest_ty, inst, inst_src);
...@@ -26787,8 +26818,8 @@ fn coerceExtra(...@@ -26787,8 +26818,8 @@ fn coerceExtra(
26787 // In this case we must add a safety check because the C pointer26818 // In this case we must add a safety check because the C pointer
26788 // could be null.26819 // could be null.
26789 const src_elem_ty = inst_ty.childType(mod);26820 const src_elem_ty = inst_ty.childType(mod);
26790 const dest_is_mut = dest_info.mutable;26821 const dest_is_mut = !dest_info.flags.is_const;
26791 const dst_elem_type = dest_info.pointee_type;26822 const dst_elem_type = dest_info.child.toType();
26792 switch (try sema.coerceInMemoryAllowed(block, dst_elem_type, src_elem_ty, dest_is_mut, target, dest_ty_src, inst_src)) {26823 switch (try sema.coerceInMemoryAllowed(block, dst_elem_type, src_elem_ty, dest_is_mut, target, dest_ty_src, inst_src)) {
26793 .ok => {},26824 .ok => {},
26794 else => break :src_c_ptr,26825 else => break :src_c_ptr,
...@@ -26798,7 +26829,7 @@ fn coerceExtra(...@@ -26798,7 +26829,7 @@ fn coerceExtra(
2679826829
26799 // cast from *T and [*]T to *anyopaque26830 // cast from *T and [*]T to *anyopaque
26800 // but don't do it if the source type is a double pointer26831 // but don't do it if the source type is a double pointer
26801 if (dest_info.pointee_type.toIntern() == .anyopaque_type and inst_ty.zigTypeTag(mod) == .Pointer) to_anyopaque: {26832 if (dest_info.child == .anyopaque_type and inst_ty.zigTypeTag(mod) == .Pointer) to_anyopaque: {
26802 if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :pointer;26833 if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :pointer;
26803 const elem_ty = inst_ty.elemType2(mod);26834 const elem_ty = inst_ty.elemType2(mod);
26804 if (elem_ty.zigTypeTag(mod) == .Pointer or elem_ty.isPtrLikeOptional(mod)) {26835 if (elem_ty.zigTypeTag(mod) == .Pointer or elem_ty.isPtrLikeOptional(mod)) {
...@@ -26819,7 +26850,7 @@ fn coerceExtra(...@@ -26819,7 +26850,7 @@ fn coerceExtra(
26819 return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src);26850 return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src);
26820 }26851 }
2682126852
26822 switch (dest_info.size) {26853 switch (dest_info.flags.size) {
26823 // coercion to C pointer26854 // coercion to C pointer
26824 .C => switch (inst_ty.zigTypeTag(mod)) {26855 .C => switch (inst_ty.zigTypeTag(mod)) {
26825 .Null => {26856 .Null => {
...@@ -26852,9 +26883,9 @@ fn coerceExtra(...@@ -26852,9 +26883,9 @@ fn coerceExtra(
26852 const inst_info = inst_ty.ptrInfo(mod);26883 const inst_info = inst_ty.ptrInfo(mod);
26853 switch (try sema.coerceInMemoryAllowed(26884 switch (try sema.coerceInMemoryAllowed(
26854 block,26885 block,
26855 dest_info.pointee_type,26886 dest_info.child.toType(),
26856 inst_info.pointee_type,26887 inst_info.child.toType(),
26857 dest_info.mutable,26888 !dest_info.flags.is_const,
26858 target,26889 target,
26859 dest_ty_src,26890 dest_ty_src,
26860 inst_src,26891 inst_src,
...@@ -26862,10 +26893,10 @@ fn coerceExtra(...@@ -26862,10 +26893,10 @@ fn coerceExtra(
26862 .ok => {},26893 .ok => {},
26863 else => break :p,26894 else => break :p,
26864 }26895 }
26865 if (inst_info.size == .Slice) {26896 if (inst_info.flags.size == .Slice) {
26866 assert(dest_info.sentinel == null);26897 assert(dest_info.sentinel == .none);
26867 if (inst_info.sentinel == null or26898 if (inst_info.sentinel == .none or
26868 !inst_info.sentinel.?.eql(try mod.intValue(dest_info.pointee_type, 0), dest_info.pointee_type, mod))26899 inst_info.sentinel != (try mod.intValue(inst_info.child.toType(), 0)).toIntern())
26869 break :p;26900 break :p;
2687026901
26871 const slice_ptr = try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty);26902 const slice_ptr = try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty);
...@@ -26875,7 +26906,7 @@ fn coerceExtra(...@@ -26875,7 +26906,7 @@ fn coerceExtra(
26875 },26906 },
26876 else => {},26907 else => {},
26877 },26908 },
26878 .One => switch (dest_info.pointee_type.zigTypeTag(mod)) {26909 .One => switch (dest_info.child.toType().zigTypeTag(mod)) {
26879 .Union => {26910 .Union => {
26880 // pointer to anonymous struct to pointer to union26911 // pointer to anonymous struct to pointer to union
26881 if (inst_ty.isSinglePointer(mod) and26912 if (inst_ty.isSinglePointer(mod) and
...@@ -26929,16 +26960,16 @@ fn coerceExtra(...@@ -26929,16 +26960,16 @@ fn coerceExtra(
26929 // we use a dummy pointer value with the required alignment.26960 // we use a dummy pointer value with the required alignment.
26930 return sema.addConstant(dest_ty, (try mod.intern(.{ .ptr = .{26961 return sema.addConstant(dest_ty, (try mod.intern(.{ .ptr = .{
26931 .ty = dest_ty.toIntern(),26962 .ty = dest_ty.toIntern(),
26932 .addr = .{ .int = (if (dest_info.@"align" != 0)26963 .addr = .{ .int = (if (dest_info.flags.alignment != .none)
26933 try mod.intValue(Type.usize, dest_info.@"align")26964 try mod.intValue(Type.usize, dest_info.flags.alignment.toByteUnitsOptional().?)
26934 else26965 else
26935 try mod.getCoerced(try dest_info.pointee_type.lazyAbiAlignment(mod), Type.usize)).toIntern() },26966 try mod.getCoerced(try dest_info.child.toType().lazyAbiAlignment(mod), Type.usize)).toIntern() },
26936 .len = (try mod.intValue(Type.usize, 0)).toIntern(),26967 .len = (try mod.intValue(Type.usize, 0)).toIntern(),
26937 } })).toValue());26968 } })).toValue());
26938 }26969 }
2693926970
26940 // pointer to tuple to slice26971 // pointer to tuple to slice
26941 if (dest_info.mutable) {26972 if (!dest_info.flags.is_const) {
26942 const err_msg = err_msg: {26973 const err_msg = err_msg: {
26943 const err_msg = try sema.errMsg(block, inst_src, "cannot cast pointer to tuple to '{}'", .{dest_ty.fmt(mod)});26974 const err_msg = try sema.errMsg(block, inst_src, "cannot cast pointer to tuple to '{}'", .{dest_ty.fmt(mod)});
26944 errdefer err_msg.deinit(sema.gpa);26975 errdefer err_msg.deinit(sema.gpa);
...@@ -26956,9 +26987,9 @@ fn coerceExtra(...@@ -26956,9 +26987,9 @@ fn coerceExtra(
2695626987
26957 switch (try sema.coerceInMemoryAllowed(26988 switch (try sema.coerceInMemoryAllowed(
26958 block,26989 block,
26959 dest_info.pointee_type,26990 dest_info.child.toType(),
26960 inst_info.pointee_type,26991 inst_info.child.toType(),
26961 dest_info.mutable,26992 !dest_info.flags.is_const,
26962 target,26993 target,
26963 dest_ty_src,26994 dest_ty_src,
26964 inst_src,26995 inst_src,
...@@ -26967,12 +26998,9 @@ fn coerceExtra(...@@ -26967,12 +26998,9 @@ fn coerceExtra(
26967 else => break :p,26998 else => break :p,
26968 }26999 }
2696927000
26970 if (dest_info.sentinel == null or inst_info.sentinel == null or27001 if (dest_info.sentinel == .none or inst_info.sentinel == .none or
26971 !dest_info.sentinel.?.eql(27002 dest_info.sentinel !=
26972 try mod.getCoerced(inst_info.sentinel.?, dest_info.pointee_type),27003 try mod.intern_pool.getCoerced(sema.gpa, inst_info.sentinel, dest_info.child))
26973 dest_info.pointee_type,
26974 mod,
26975 ))
26976 break :p;27004 break :p;
2697727005
26978 const slice_ptr = try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty);27006 const slice_ptr = try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty);
...@@ -28098,41 +28126,41 @@ fn coerceInMemoryAllowedPtrs(...@@ -28098,41 +28126,41 @@ fn coerceInMemoryAllowedPtrs(
28098 const dest_info = dest_ptr_ty.ptrInfo(mod);28126 const dest_info = dest_ptr_ty.ptrInfo(mod);
28099 const src_info = src_ptr_ty.ptrInfo(mod);28127 const src_info = src_ptr_ty.ptrInfo(mod);
2810028128
28101 const ok_ptr_size = src_info.size == dest_info.size or28129 const ok_ptr_size = src_info.flags.size == dest_info.flags.size or
28102 src_info.size == .C or dest_info.size == .C;28130 src_info.flags.size == .C or dest_info.flags.size == .C;
28103 if (!ok_ptr_size) {28131 if (!ok_ptr_size) {
28104 return InMemoryCoercionResult{ .ptr_size = .{28132 return InMemoryCoercionResult{ .ptr_size = .{
28105 .actual = src_info.size,28133 .actual = src_info.flags.size,
28106 .wanted = dest_info.size,28134 .wanted = dest_info.flags.size,
28107 } };28135 } };
28108 }28136 }
2810928137
28110 const ok_cv_qualifiers =28138 const ok_cv_qualifiers =
28111 (src_info.mutable or !dest_info.mutable) and28139 (!src_info.flags.is_const or dest_info.flags.is_const) and
28112 (!src_info.@"volatile" or dest_info.@"volatile");28140 (!src_info.flags.is_volatile or dest_info.flags.is_volatile);
2811328141
28114 if (!ok_cv_qualifiers) {28142 if (!ok_cv_qualifiers) {
28115 return InMemoryCoercionResult{ .ptr_qualifiers = .{28143 return InMemoryCoercionResult{ .ptr_qualifiers = .{
28116 .actual_const = !src_info.mutable,28144 .actual_const = src_info.flags.is_const,
28117 .wanted_const = !dest_info.mutable,28145 .wanted_const = dest_info.flags.is_const,
28118 .actual_volatile = src_info.@"volatile",28146 .actual_volatile = src_info.flags.is_volatile,
28119 .wanted_volatile = dest_info.@"volatile",28147 .wanted_volatile = dest_info.flags.is_volatile,
28120 } };28148 } };
28121 }28149 }
2812228150
28123 if (dest_info.@"addrspace" != src_info.@"addrspace") {28151 if (dest_info.flags.address_space != src_info.flags.address_space) {
28124 return InMemoryCoercionResult{ .ptr_addrspace = .{28152 return InMemoryCoercionResult{ .ptr_addrspace = .{
28125 .actual = src_info.@"addrspace",28153 .actual = src_info.flags.address_space,
28126 .wanted = dest_info.@"addrspace",28154 .wanted = dest_info.flags.address_space,
28127 } };28155 } };
28128 }28156 }
2812928157
28130 const child = try sema.coerceInMemoryAllowed(block, dest_info.pointee_type, src_info.pointee_type, dest_info.mutable, target, dest_src, src_src);28158 const child = try sema.coerceInMemoryAllowed(block, dest_info.child.toType(), src_info.child.toType(), !dest_info.flags.is_const, target, dest_src, src_src);
28131 if (child != .ok) {28159 if (child != .ok) {
28132 return InMemoryCoercionResult{ .ptr_child = .{28160 return InMemoryCoercionResult{ .ptr_child = .{
28133 .child = try child.dupe(sema.arena),28161 .child = try child.dupe(sema.arena),
28134 .actual = src_info.pointee_type,28162 .actual = src_info.child.toType(),
28135 .wanted = dest_info.pointee_type,28163 .wanted = dest_info.child.toType(),
28136 } };28164 } };
28137 }28165 }
2813828166
...@@ -28149,28 +28177,31 @@ fn coerceInMemoryAllowedPtrs(...@@ -28149,28 +28177,31 @@ fn coerceInMemoryAllowedPtrs(
28149 } };28177 } };
28150 }28178 }
2815128179
28152 if (src_info.host_size != dest_info.host_size or28180 if (src_info.packed_offset.host_size != dest_info.packed_offset.host_size or
28153 src_info.bit_offset != dest_info.bit_offset)28181 src_info.packed_offset.bit_offset != dest_info.packed_offset.bit_offset)
28154 {28182 {
28155 return InMemoryCoercionResult{ .ptr_bit_range = .{28183 return InMemoryCoercionResult{ .ptr_bit_range = .{
28156 .actual_host = src_info.host_size,28184 .actual_host = src_info.packed_offset.host_size,
28157 .wanted_host = dest_info.host_size,28185 .wanted_host = dest_info.packed_offset.host_size,
28158 .actual_offset = src_info.bit_offset,28186 .actual_offset = src_info.packed_offset.bit_offset,
28159 .wanted_offset = dest_info.bit_offset,28187 .wanted_offset = dest_info.packed_offset.bit_offset,
28160 } };28188 } };
28161 }28189 }
2816228190
28163 const ok_sent = dest_info.sentinel == null or src_info.size == .C or28191 const ok_sent = dest_info.sentinel == .none or src_info.flags.size == .C or
28164 (src_info.sentinel != null and dest_info.sentinel.?.eql(28192 (src_info.sentinel != .none and
28165 try mod.getCoerced(src_info.sentinel.?, dest_info.pointee_type),28193 dest_info.sentinel == try mod.intern_pool.getCoerced(sema.gpa, src_info.sentinel, dest_info.child));
28166 dest_info.pointee_type,
28167 sema.mod,
28168 ));
28169 if (!ok_sent) {28194 if (!ok_sent) {
28170 return InMemoryCoercionResult{ .ptr_sentinel = .{28195 return InMemoryCoercionResult{ .ptr_sentinel = .{
28171 .actual = src_info.sentinel orelse Value.@"unreachable",28196 .actual = switch (src_info.sentinel) {
28172 .wanted = dest_info.sentinel orelse Value.@"unreachable",28197 .none => Value.@"unreachable",
28173 .ty = dest_info.pointee_type,28198 else => src_info.sentinel.toValue(),
28199 },
28200 .wanted = switch (dest_info.sentinel) {
28201 .none => Value.@"unreachable",
28202 else => dest_info.sentinel.toValue(),
28203 },
28204 .ty = dest_info.child.toType(),
28174 } };28205 } };
28175 }28206 }
2817628207
...@@ -28178,22 +28209,14 @@ fn coerceInMemoryAllowedPtrs(...@@ -28178,22 +28209,14 @@ fn coerceInMemoryAllowedPtrs(
28178 // In this case, if they share the same child type, no need to resolve28209 // In this case, if they share the same child type, no need to resolve
28179 // pointee type alignment. Otherwise both pointee types must have their alignment28210 // pointee type alignment. Otherwise both pointee types must have their alignment
28180 // resolved and we compare the alignment numerically.28211 // resolved and we compare the alignment numerically.
28181 alignment: {28212 if (src_info.flags.alignment != .none or dest_info.flags.alignment != .none or
28182 if (src_info.@"align" == 0 and dest_info.@"align" == 0 and28213 dest_info.child != src_info.child)
28183 dest_info.pointee_type.eql(src_info.pointee_type, sema.mod))28214 {
28184 {28215 const src_align = src_info.flags.alignment.toByteUnitsOptional() orelse
28185 break :alignment;28216 src_info.child.toType().abiAlignment(mod);
28186 }
28187
28188 const src_align = if (src_info.@"align" != 0)
28189 src_info.@"align"
28190 else
28191 src_info.pointee_type.abiAlignment(mod);
2819228217
28193 const dest_align = if (dest_info.@"align" != 0)28218 const dest_align = dest_info.flags.alignment.toByteUnitsOptional() orelse
28194 dest_info.@"align"28219 dest_info.child.toType().abiAlignment(mod);
28195 else
28196 dest_info.pointee_type.abiAlignment(mod);
2819728220
28198 if (dest_align > src_align) {28221 if (dest_align > src_align) {
28199 return InMemoryCoercionResult{ .ptr_alignment = .{28222 return InMemoryCoercionResult{ .ptr_alignment = .{
...@@ -28201,8 +28224,6 @@ fn coerceInMemoryAllowedPtrs(...@@ -28201,8 +28224,6 @@ fn coerceInMemoryAllowedPtrs(
28201 .wanted = dest_align,28224 .wanted = dest_align,
28202 } };28225 } };
28203 }28226 }
28204
28205 break :alignment;
28206 }28227 }
2820728228
28208 return .ok;28229 return .ok;
...@@ -28367,7 +28388,7 @@ fn storePtr2(...@@ -28367,7 +28388,7 @@ fn storePtr2(
28367 try sema.requireRuntimeBlock(block, src, runtime_src);28388 try sema.requireRuntimeBlock(block, src, runtime_src);
28368 try sema.queueFullTypeResolution(elem_ty);28389 try sema.queueFullTypeResolution(elem_ty);
2836928390
28370 if (ptr_ty.ptrInfo(mod).vector_index == .runtime) {28391 if (ptr_ty.ptrInfo(mod).flags.vector_index == .runtime) {
28371 const ptr_inst = Air.refToIndex(ptr).?;28392 const ptr_inst = Air.refToIndex(ptr).?;
28372 const air_tags = sema.air_instructions.items(.tag);28393 const air_tags = sema.air_instructions.items(.tag);
28373 if (air_tags[ptr_inst] == .ptr_elem_ptr) {28394 if (air_tags[ptr_inst] == .ptr_elem_ptr) {
...@@ -29219,11 +29240,14 @@ fn beginComptimePtrLoad(...@@ -29219,11 +29240,14 @@ fn beginComptimePtrLoad(
29219 // It's possible that we're loading a [N]T, in which case we'd like to slice29240 // It's possible that we're loading a [N]T, in which case we'd like to slice
29220 // the pointee array directly from our parent array.29241 // the pointee array directly from our parent array.
29221 if (load_ty.isArrayOrVector(mod) and load_ty.childType(mod).eql(elem_ty, mod)) {29242 if (load_ty.isArrayOrVector(mod) and load_ty.childType(mod).eql(elem_ty, mod)) {
29222 const N = try sema.usizeCast(block, src, load_ty.arrayLenIncludingSentinel(mod));29243 const len = try sema.usizeCast(block, src, load_ty.arrayLenIncludingSentinel(mod));
29223 const elem_idx = try sema.usizeCast(block, src, elem_ptr.index);29244 const elem_idx = try sema.usizeCast(block, src, elem_ptr.index);
29224 deref.pointee = if (elem_ptr.index + N <= check_len) TypedValue{29245 deref.pointee = if (elem_ptr.index + len <= check_len) TypedValue{
29225 .ty = try Type.array(sema.arena, N, null, elem_ty, mod),29246 .ty = try mod.arrayType(.{
29226 .val = try array_tv.val.sliceArray(mod, sema.arena, elem_idx, elem_idx + N),29247 .len = len,
29248 .child = elem_ty.toIntern(),
29249 }),
29250 .val = try array_tv.val.sliceArray(mod, sema.arena, elem_idx, elem_idx + len),
29227 } else null;29251 } else null;
29228 break :blk deref;29252 break :blk deref;
29229 }29253 }
...@@ -29410,42 +29434,38 @@ fn checkPtrAttributes(sema: *Sema, dest_ty: Type, inst_ty: Type, in_memory_resul...@@ -29410,42 +29434,38 @@ fn checkPtrAttributes(sema: *Sema, dest_ty: Type, inst_ty: Type, in_memory_resul
29410 const mod = sema.mod;29434 const mod = sema.mod;
29411 const dest_info = dest_ty.ptrInfo(mod);29435 const dest_info = dest_ty.ptrInfo(mod);
29412 const inst_info = inst_ty.ptrInfo(mod);29436 const inst_info = inst_ty.ptrInfo(mod);
29413 const len0 = (inst_info.pointee_type.zigTypeTag(mod) == .Array and (inst_info.pointee_type.arrayLenIncludingSentinel(mod) == 0 or29437 const len0 = (inst_info.child.toType().zigTypeTag(mod) == .Array and (inst_info.child.toType().arrayLenIncludingSentinel(mod) == 0 or
29414 (inst_info.pointee_type.arrayLen(mod) == 0 and dest_info.sentinel == null and dest_info.size != .C and dest_info.size != .Many))) or29438 (inst_info.child.toType().arrayLen(mod) == 0 and dest_info.sentinel == .none and dest_info.flags.size != .C and dest_info.flags.size != .Many))) or
29415 (inst_info.pointee_type.isTuple(mod) and inst_info.pointee_type.structFieldCount(mod) == 0);29439 (inst_info.child.toType().isTuple(mod) and inst_info.child.toType().structFieldCount(mod) == 0);
2941629440
29417 const ok_cv_qualifiers =29441 const ok_cv_qualifiers =
29418 ((inst_info.mutable or !dest_info.mutable) or len0) and29442 ((!inst_info.flags.is_const or dest_info.flags.is_const) or len0) and
29419 (!inst_info.@"volatile" or dest_info.@"volatile");29443 (!inst_info.flags.is_volatile or dest_info.flags.is_volatile);
2942029444
29421 if (!ok_cv_qualifiers) {29445 if (!ok_cv_qualifiers) {
29422 in_memory_result.* = .{ .ptr_qualifiers = .{29446 in_memory_result.* = .{ .ptr_qualifiers = .{
29423 .actual_const = !inst_info.mutable,29447 .actual_const = inst_info.flags.is_const,
29424 .wanted_const = !dest_info.mutable,29448 .wanted_const = dest_info.flags.is_const,
29425 .actual_volatile = inst_info.@"volatile",29449 .actual_volatile = inst_info.flags.is_volatile,
29426 .wanted_volatile = dest_info.@"volatile",29450 .wanted_volatile = dest_info.flags.is_volatile,
29427 } };29451 } };
29428 return false;29452 return false;
29429 }29453 }
29430 if (dest_info.@"addrspace" != inst_info.@"addrspace") {29454 if (dest_info.flags.address_space != inst_info.flags.address_space) {
29431 in_memory_result.* = .{ .ptr_addrspace = .{29455 in_memory_result.* = .{ .ptr_addrspace = .{
29432 .actual = inst_info.@"addrspace",29456 .actual = inst_info.flags.address_space,
29433 .wanted = dest_info.@"addrspace",29457 .wanted = dest_info.flags.address_space,
29434 } };29458 } };
29435 return false;29459 return false;
29436 }29460 }
29437 if (inst_info.@"align" == 0 and dest_info.@"align" == 0) return true;29461 if (inst_info.flags.alignment == .none and dest_info.flags.alignment == .none) return true;
29438 if (len0) return true;29462 if (len0) return true;
2943929463
29440 const inst_align = if (inst_info.@"align" != 0)29464 const inst_align = inst_info.flags.alignment.toByteUnitsOptional() orelse
29441 inst_info.@"align"29465 inst_info.child.toType().abiAlignment(mod);
29442 else
29443 inst_info.pointee_type.abiAlignment(mod);
2944429466
29445 const dest_align = if (dest_info.@"align" != 0)29467 const dest_align = dest_info.flags.alignment.toByteUnitsOptional() orelse
29446 dest_info.@"align"29468 dest_info.child.toType().abiAlignment(mod);
29447 else
29448 dest_info.pointee_type.abiAlignment(mod);
2944929469
29450 if (dest_align > inst_align) {29470 if (dest_align > inst_align) {
29451 in_memory_result.* = .{ .ptr_alignment = .{29471 in_memory_result.* = .{ .ptr_alignment = .{
...@@ -29882,9 +29902,13 @@ fn coerceTupleToSlicePtrs(...@@ -29882,9 +29902,13 @@ fn coerceTupleToSlicePtrs(
29882 const tuple_ty = sema.typeOf(ptr_tuple).childType(mod);29902 const tuple_ty = sema.typeOf(ptr_tuple).childType(mod);
29883 const tuple = try sema.analyzeLoad(block, tuple_src, ptr_tuple, tuple_src);29903 const tuple = try sema.analyzeLoad(block, tuple_src, ptr_tuple, tuple_src);
29884 const slice_info = slice_ty.ptrInfo(mod);29904 const slice_info = slice_ty.ptrInfo(mod);
29885 const array_ty = try Type.array(sema.arena, tuple_ty.structFieldCount(mod), slice_info.sentinel, slice_info.pointee_type, sema.mod);29905 const array_ty = try mod.arrayType(.{
29906 .len = tuple_ty.structFieldCount(mod),
29907 .sentinel = slice_info.sentinel,
29908 .child = slice_info.child,
29909 });
29886 const array_inst = try sema.coerceTupleToArray(block, array_ty, slice_ty_src, tuple, tuple_src);29910 const array_inst = try sema.coerceTupleToArray(block, array_ty, slice_ty_src, tuple, tuple_src);
29887 if (slice_info.@"align" != 0) {29911 if (slice_info.flags.alignment != .none) {
29888 return sema.fail(block, slice_ty_src, "TODO: override the alignment of the array decl we create here", .{});29912 return sema.fail(block, slice_ty_src, "TODO: override the alignment of the array decl we create here", .{});
29889 }29913 }
29890 const ptr_array = try sema.analyzeRef(block, slice_ty_src, array_inst);29914 const ptr_array = try sema.analyzeRef(block, slice_ty_src, array_inst);
...@@ -29903,9 +29927,9 @@ fn coerceTupleToArrayPtrs(...@@ -29903,9 +29927,9 @@ fn coerceTupleToArrayPtrs(
29903 const mod = sema.mod;29927 const mod = sema.mod;
29904 const tuple = try sema.analyzeLoad(block, tuple_src, ptr_tuple, tuple_src);29928 const tuple = try sema.analyzeLoad(block, tuple_src, ptr_tuple, tuple_src);
29905 const ptr_info = ptr_array_ty.ptrInfo(mod);29929 const ptr_info = ptr_array_ty.ptrInfo(mod);
29906 const array_ty = ptr_info.pointee_type;29930 const array_ty = ptr_info.child.toType();
29907 const array_inst = try sema.coerceTupleToArray(block, array_ty, array_ty_src, tuple, tuple_src);29931 const array_inst = try sema.coerceTupleToArray(block, array_ty, array_ty_src, tuple, tuple_src);
29908 if (ptr_info.@"align" != 0) {29932 if (ptr_info.flags.alignment != .none) {
29909 return sema.fail(block, array_ty_src, "TODO: override the alignment of the array decl we create here", .{});29933 return sema.fail(block, array_ty_src, "TODO: override the alignment of the array decl we create here", .{});
29910 }29934 }
29911 const ptr_array = try sema.analyzeRef(block, array_ty_src, array_inst);29935 const ptr_array = try sema.analyzeRef(block, array_ty_src, array_inst);
...@@ -30244,7 +30268,7 @@ fn refValue(sema: *Sema, block: *Block, ty: Type, val: Value) !Value {...@@ -30244,7 +30268,7 @@ fn refValue(sema: *Sema, block: *Block, ty: Type, val: Value) !Value {
30244 const decl = try anon_decl.finish(30268 const decl = try anon_decl.finish(
30245 ty,30269 ty,
30246 val,30270 val,
30247 0, // default alignment30271 .none, // default alignment
30248 );30272 );
30249 try sema.maybeQueueFuncBodyAnalysis(decl);30273 try sema.maybeQueueFuncBodyAnalysis(decl);
30250 try mod.declareDeclDependency(sema.owner_decl_index, decl);30274 try mod.declareDeclDependency(sema.owner_decl_index, decl);
...@@ -30285,7 +30309,7 @@ fn analyzeDeclRefInner(sema: *Sema, decl_index: Decl.Index, analyze_fn_body: boo...@@ -30285,7 +30309,7 @@ fn analyzeDeclRefInner(sema: *Sema, decl_index: Decl.Index, analyze_fn_body: boo
30285 const ptr_ty = try mod.ptrType(.{30309 const ptr_ty = try mod.ptrType(.{
30286 .child = decl_tv.ty.toIntern(),30310 .child = decl_tv.ty.toIntern(),
30287 .flags = .{30311 .flags = .{
30288 .alignment = InternPool.Alignment.fromByteUnits(decl.@"align"),30312 .alignment = decl.alignment,
30289 .is_const = if (decl.val.getVariable(mod)) |variable| variable.is_const else true,30313 .is_const = if (decl.val.getVariable(mod)) |variable| variable.is_const else true,
30290 .address_space = decl.@"addrspace",30314 .address_space = decl.@"addrspace",
30291 },30315 },
...@@ -30315,12 +30339,13 @@ fn analyzeRef(...@@ -30315,12 +30339,13 @@ fn analyzeRef(
30315 src: LazySrcLoc,30339 src: LazySrcLoc,
30316 operand: Air.Inst.Ref,30340 operand: Air.Inst.Ref,
30317) CompileError!Air.Inst.Ref {30341) CompileError!Air.Inst.Ref {
30342 const mod = sema.mod;
30318 const operand_ty = sema.typeOf(operand);30343 const operand_ty = sema.typeOf(operand);
3031930344
30320 if (try sema.resolveMaybeUndefVal(operand)) |val| {30345 if (try sema.resolveMaybeUndefVal(operand)) |val| {
30321 switch (sema.mod.intern_pool.indexToKey(val.toIntern())) {30346 switch (mod.intern_pool.indexToKey(val.toIntern())) {
30322 .extern_func => |extern_func| return sema.analyzeDeclRef(extern_func.decl),30347 .extern_func => |extern_func| return sema.analyzeDeclRef(extern_func.decl),
30323 .func => |func| return sema.analyzeDeclRef(sema.mod.funcPtr(func.index).owner_decl),30348 .func => |func| return sema.analyzeDeclRef(mod.funcPtr(func.index).owner_decl),
30324 else => {},30349 else => {},
30325 }30350 }
30326 var anon_decl = try block.startAnonDecl();30351 var anon_decl = try block.startAnonDecl();
...@@ -30328,20 +30353,22 @@ fn analyzeRef(...@@ -30328,20 +30353,22 @@ fn analyzeRef(
30328 return sema.analyzeDeclRef(try anon_decl.finish(30353 return sema.analyzeDeclRef(try anon_decl.finish(
30329 operand_ty,30354 operand_ty,
30330 val,30355 val,
30331 0, // default alignment30356 .none, // default alignment
30332 ));30357 ));
30333 }30358 }
3033430359
30335 try sema.requireRuntimeBlock(block, src, null);30360 try sema.requireRuntimeBlock(block, src, null);
30336 const address_space = target_util.defaultAddressSpace(sema.mod.getTarget(), .local);30361 const address_space = target_util.defaultAddressSpace(mod.getTarget(), .local);
30337 const ptr_type = try Type.ptr(sema.arena, sema.mod, .{30362 const ptr_type = try mod.ptrType(.{
30338 .pointee_type = operand_ty,30363 .child = operand_ty.toIntern(),
30339 .mutable = false,30364 .flags = .{
30340 .@"addrspace" = address_space,30365 .is_const = true,
30366 .address_space = address_space,
30367 },
30341 });30368 });
30342 const mut_ptr_type = try Type.ptr(sema.arena, sema.mod, .{30369 const mut_ptr_type = try mod.ptrType(.{
30343 .pointee_type = operand_ty,30370 .child = operand_ty.toIntern(),
30344 .@"addrspace" = address_space,30371 .flags = .{ .address_space = address_space },
30345 });30372 });
30346 const alloc = try block.addTy(.alloc, mut_ptr_type);30373 const alloc = try block.addTy(.alloc, mut_ptr_type);
30347 try sema.storePtr(block, src, alloc, operand);30374 try sema.storePtr(block, src, alloc, operand);
...@@ -30374,7 +30401,7 @@ fn analyzeLoad(...@@ -30374,7 +30401,7 @@ fn analyzeLoad(
30374 }30401 }
30375 }30402 }
3037630403
30377 if (ptr_ty.ptrInfo(mod).vector_index == .runtime) {30404 if (ptr_ty.ptrInfo(mod).flags.vector_index == .runtime) {
30378 const ptr_inst = Air.refToIndex(ptr).?;30405 const ptr_inst = Air.refToIndex(ptr).?;
30379 const air_tags = sema.air_instructions.items(.tag);30406 const air_tags = sema.air_instructions.items(.tag);
30380 if (air_tags[ptr_inst] == .ptr_elem_ptr) {30407 if (air_tags[ptr_inst] == .ptr_elem_ptr) {
...@@ -30900,20 +30927,24 @@ fn analyzeSlice(...@@ -30900,20 +30927,24 @@ fn analyzeSlice(
30900 const opt_new_len_val = try sema.resolveDefinedValue(block, src, new_len);30927 const opt_new_len_val = try sema.resolveDefinedValue(block, src, new_len);
3090130928
30902 const new_ptr_ty_info = new_ptr_ty.ptrInfo(mod);30929 const new_ptr_ty_info = new_ptr_ty.ptrInfo(mod);
30903 const new_allowzero = new_ptr_ty_info.@"allowzero" and sema.typeOf(ptr).ptrSize(mod) != .C;30930 const new_allowzero = new_ptr_ty_info.flags.is_allowzero and sema.typeOf(ptr).ptrSize(mod) != .C;
3090430931
30905 if (opt_new_len_val) |new_len_val| {30932 if (opt_new_len_val) |new_len_val| {
30906 const new_len_int = new_len_val.toUnsignedInt(mod);30933 const new_len_int = new_len_val.toUnsignedInt(mod);
3090730934
30908 const return_ty = try Type.ptr(sema.arena, mod, .{30935 const return_ty = try mod.ptrType(.{
30909 .pointee_type = try Type.array(sema.arena, new_len_int, sentinel, elem_ty, mod),30936 .child = (try mod.arrayType(.{
30910 .sentinel = null,30937 .len = new_len_int,
30911 .@"align" = new_ptr_ty_info.@"align",30938 .sentinel = if (sentinel) |s| s.toIntern() else .none,
30912 .@"addrspace" = new_ptr_ty_info.@"addrspace",30939 .child = elem_ty.toIntern(),
30913 .mutable = new_ptr_ty_info.mutable,30940 })).toIntern(),
30914 .@"allowzero" = new_allowzero,30941 .flags = .{
30915 .@"volatile" = new_ptr_ty_info.@"volatile",30942 .alignment = new_ptr_ty_info.flags.alignment,
30916 .size = .One,30943 .is_const = new_ptr_ty_info.flags.is_const,
30944 .is_allowzero = new_allowzero,
30945 .is_volatile = new_ptr_ty_info.flags.is_volatile,
30946 .address_space = new_ptr_ty_info.flags.address_space,
30947 },
30917 });30948 });
3091830949
30919 const opt_new_ptr_val = try sema.resolveMaybeUndefVal(new_ptr);30950 const opt_new_ptr_val = try sema.resolveMaybeUndefVal(new_ptr);
...@@ -30962,15 +30993,17 @@ fn analyzeSlice(...@@ -30962,15 +30993,17 @@ fn analyzeSlice(
30962 return sema.fail(block, src, "non-zero length slice of undefined pointer", .{});30993 return sema.fail(block, src, "non-zero length slice of undefined pointer", .{});
30963 }30994 }
3096430995
30965 const return_ty = try Type.ptr(sema.arena, mod, .{30996 const return_ty = try mod.ptrType(.{
30966 .pointee_type = elem_ty,30997 .child = elem_ty.toIntern(),
30967 .sentinel = sentinel,30998 .sentinel = if (sentinel) |s| s.toIntern() else .none,
30968 .@"align" = new_ptr_ty_info.@"align",30999 .flags = .{
30969 .@"addrspace" = new_ptr_ty_info.@"addrspace",31000 .size = .Slice,
30970 .mutable = new_ptr_ty_info.mutable,31001 .alignment = new_ptr_ty_info.flags.alignment,
30971 .@"allowzero" = new_allowzero,31002 .is_const = new_ptr_ty_info.flags.is_const,
30972 .@"volatile" = new_ptr_ty_info.@"volatile",31003 .is_volatile = new_ptr_ty_info.flags.is_volatile,
30973 .size = .Slice,31004 .is_allowzero = new_allowzero,
31005 .address_space = new_ptr_ty_info.flags.address_space,
31006 },
30974 });31007 });
3097531008
30976 try sema.requireRuntimeBlock(block, src, runtime_src.?);31009 try sema.requireRuntimeBlock(block, src, runtime_src.?);
...@@ -31716,7 +31749,7 @@ const PeerResolveStrategy = enum {...@@ -31716,7 +31749,7 @@ const PeerResolveStrategy = enum {
31716 .Int => .fixed_int,31749 .Int => .fixed_int,
31717 .ComptimeFloat => .comptime_float,31750 .ComptimeFloat => .comptime_float,
31718 .Float => .fixed_float,31751 .Float => .fixed_float,
31719 .Pointer => if (ty.ptrInfo(mod).size == .C) .c_ptr else .ptr,31752 .Pointer => if (ty.ptrInfo(mod).flags.size == .C) .c_ptr else .ptr,
31720 .Array => .array,31753 .Array => .array,
31721 .Vector => .vector,31754 .Vector => .vector,
31722 .Optional => .optional,31755 .Optional => .optional,
...@@ -32141,7 +32174,7 @@ fn resolvePeerTypesInner(...@@ -32141,7 +32174,7 @@ fn resolvePeerTypesInner(
32141 },32174 },
3214232175
32143 .c_ptr => {32176 .c_ptr => {
32144 var opt_ptr_info: ?Type.Payload.Pointer.Data = null;32177 var opt_ptr_info: ?InternPool.Key.PtrType = null;
32145 var first_idx: usize = undefined;32178 var first_idx: usize = undefined;
32146 for (peer_tys, peer_vals, 0..) |opt_ty, opt_val, i| {32179 for (peer_tys, peer_vals, 0..) |opt_ty, opt_val, i| {
32147 const ty = opt_ty orelse continue;32180 const ty = opt_ty orelse continue;
...@@ -32172,42 +32205,47 @@ fn resolvePeerTypesInner(...@@ -32172,42 +32205,47 @@ fn resolvePeerTypesInner(
3217232205
32173 var ptr_info = opt_ptr_info orelse {32206 var ptr_info = opt_ptr_info orelse {
32174 opt_ptr_info = peer_info;32207 opt_ptr_info = peer_info;
32175 opt_ptr_info.?.size = .C;32208 opt_ptr_info.?.flags.size = .C;
32176 first_idx = i;32209 first_idx = i;
32177 continue;32210 continue;
32178 };32211 };
3217932212
32180 // Try peer -> cur, then cur -> peer32213 // Try peer -> cur, then cur -> peer
32181 ptr_info.pointee_type = (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.pointee_type, peer_info.pointee_type)) orelse {32214 ptr_info.child = ((try sema.resolvePairInMemoryCoercible(block, src, ptr_info.child.toType(), peer_info.child.toType())) orelse {
32182 return .{ .conflict = .{32215 return .{ .conflict = .{
32183 .peer_idx_a = first_idx,32216 .peer_idx_a = first_idx,
32184 .peer_idx_b = i,32217 .peer_idx_b = i,
32185 } };32218 } };
32186 };32219 }).toIntern();
3218732220
32188 if (ptr_info.sentinel != null and peer_info.sentinel != null) {32221 if (ptr_info.sentinel != .none and peer_info.sentinel != .none) {
32189 const peer_sent = try mod.getCoerced(ptr_info.sentinel.?, ptr_info.pointee_type);32222 const peer_sent = try mod.intern_pool.getCoerced(sema.gpa, ptr_info.sentinel, ptr_info.child);
32190 const ptr_sent = try mod.getCoerced(peer_info.sentinel.?, ptr_info.pointee_type);32223 const ptr_sent = try mod.intern_pool.getCoerced(sema.gpa, peer_info.sentinel, ptr_info.child);
32191 if (ptr_sent.eql(peer_sent, ptr_info.pointee_type, mod)) {32224 if (ptr_sent == peer_sent) {
32192 ptr_info.sentinel = ptr_sent;32225 ptr_info.sentinel = ptr_sent;
32193 } else {32226 } else {
32194 ptr_info.sentinel = null;32227 ptr_info.sentinel = .none;
32195 }32228 }
32196 } else {32229 } else {
32197 ptr_info.sentinel = null;32230 ptr_info.sentinel = .none;
32198 }32231 }
3219932232
32200 // Note that the align can be always non-zero; Type.ptr will canonicalize it32233 // Note that the align can be always non-zero; Module.ptrType will canonicalize it
32201 ptr_info.@"align" = @min(ptr_info.alignment(mod), peer_info.alignment(mod));32234 ptr_info.flags.alignment = Alignment.fromByteUnits(@min(
32202 if (ptr_info.@"addrspace" != peer_info.@"addrspace") {32235 ptr_info.flags.alignment.toByteUnitsOptional() orelse
32236 ptr_info.child.toType().abiAlignment(mod),
32237 peer_info.flags.alignment.toByteUnitsOptional() orelse
32238 peer_info.child.toType().abiAlignment(mod),
32239 ));
32240 if (ptr_info.flags.address_space != peer_info.flags.address_space) {
32203 return .{ .conflict = .{32241 return .{ .conflict = .{
32204 .peer_idx_a = first_idx,32242 .peer_idx_a = first_idx,
32205 .peer_idx_b = i,32243 .peer_idx_b = i,
32206 } };32244 } };
32207 }32245 }
3220832246
32209 if (ptr_info.bit_offset != peer_info.bit_offset or32247 if (ptr_info.packed_offset.bit_offset != peer_info.packed_offset.bit_offset or
32210 ptr_info.host_size != peer_info.host_size)32248 ptr_info.packed_offset.host_size != peer_info.packed_offset.host_size)
32211 {32249 {
32212 return .{ .conflict = .{32250 return .{ .conflict = .{
32213 .peer_idx_a = first_idx,32251 .peer_idx_a = first_idx,
...@@ -32215,12 +32253,12 @@ fn resolvePeerTypesInner(...@@ -32215,12 +32253,12 @@ fn resolvePeerTypesInner(
32215 } };32253 } };
32216 }32254 }
3221732255
32218 ptr_info.mutable = ptr_info.mutable and peer_info.mutable;32256 ptr_info.flags.is_const = ptr_info.flags.is_const or peer_info.flags.is_const;
32219 ptr_info.@"volatile" = ptr_info.@"volatile" or peer_info.@"volatile";32257 ptr_info.flags.is_volatile = ptr_info.flags.is_volatile or peer_info.flags.is_volatile;
3222032258
32221 opt_ptr_info = ptr_info;32259 opt_ptr_info = ptr_info;
32222 }32260 }
32223 return .{ .success = try Type.ptr(sema.arena, mod, opt_ptr_info.?) };32261 return .{ .success = try mod.ptrType(opt_ptr_info.?) };
32224 },32262 },
3222532263
32226 .ptr => {32264 .ptr => {
...@@ -32228,17 +32266,19 @@ fn resolvePeerTypesInner(...@@ -32228,17 +32266,19 @@ fn resolvePeerTypesInner(
32228 // if there were no actual slices. Else, we want the slice index to report a conflict.32266 // if there were no actual slices. Else, we want the slice index to report a conflict.
32229 var opt_slice_idx: ?usize = null;32267 var opt_slice_idx: ?usize = null;
3223032268
32231 var opt_ptr_info: ?Type.Payload.Pointer.Data = null;32269 var opt_ptr_info: ?InternPool.Key.PtrType = null;
32232 var first_idx: usize = undefined;32270 var first_idx: usize = undefined;
32233 var other_idx: usize = undefined; // We sometimes need a second peer index to report a generic error32271 var other_idx: usize = undefined; // We sometimes need a second peer index to report a generic error
3223432272
32235 for (peer_tys, 0..) |opt_ty, i| {32273 for (peer_tys, 0..) |opt_ty, i| {
32236 const ty = opt_ty orelse continue;32274 const ty = opt_ty orelse continue;
32237 const peer_info: Type.Payload.Pointer.Data = switch (ty.zigTypeTag(mod)) {32275 const peer_info: InternPool.Key.PtrType = switch (ty.zigTypeTag(mod)) {
32238 .Pointer => ty.ptrInfo(mod),32276 .Pointer => ty.ptrInfo(mod),
32239 .Fn => .{32277 .Fn => .{
32240 .pointee_type = ty,32278 .child = ty.toIntern(),
32241 .@"addrspace" = target_util.defaultAddressSpace(target, .global_constant),32279 .flags = .{
32280 .address_space = target_util.defaultAddressSpace(target, .global_constant),
32281 },
32242 },32282 },
32243 else => return .{ .conflict = .{32283 else => return .{ .conflict = .{
32244 .peer_idx_a = strat_reason,32284 .peer_idx_a = strat_reason,
...@@ -32246,7 +32286,7 @@ fn resolvePeerTypesInner(...@@ -32246,7 +32286,7 @@ fn resolvePeerTypesInner(
32246 } },32286 } },
32247 };32287 };
3224832288
32249 switch (peer_info.size) {32289 switch (peer_info.flags.size) {
32250 .One, .Many => {},32290 .One, .Many => {},
32251 .Slice => opt_slice_idx = i,32291 .Slice => opt_slice_idx = i,
32252 .C => return .{ .conflict = .{32292 .C => return .{ .conflict = .{
...@@ -32270,51 +32310,56 @@ fn resolvePeerTypesInner(...@@ -32270,51 +32310,56 @@ fn resolvePeerTypesInner(
32270 } };32310 } };
3227132311
32272 // Note that the align can be always non-zero; Type.ptr will canonicalize it32312 // Note that the align can be always non-zero; Type.ptr will canonicalize it
32273 ptr_info.@"align" = @min(ptr_info.alignment(mod), peer_info.alignment(mod));32313 ptr_info.flags.alignment = Alignment.fromByteUnits(@min(
32314 ptr_info.flags.alignment.toByteUnitsOptional() orelse
32315 ptr_info.child.toType().abiAlignment(mod),
32316 peer_info.flags.alignment.toByteUnitsOptional() orelse
32317 peer_info.child.toType().abiAlignment(mod),
32318 ));
3227432319
32275 if (ptr_info.@"addrspace" != peer_info.@"addrspace") {32320 if (ptr_info.flags.address_space != peer_info.flags.address_space) {
32276 return generic_err;32321 return generic_err;
32277 }32322 }
3227832323
32279 if (ptr_info.bit_offset != peer_info.bit_offset or32324 if (ptr_info.packed_offset.bit_offset != peer_info.packed_offset.bit_offset or
32280 ptr_info.host_size != peer_info.host_size)32325 ptr_info.packed_offset.host_size != peer_info.packed_offset.host_size)
32281 {32326 {
32282 return generic_err;32327 return generic_err;
32283 }32328 }
3228432329
32285 ptr_info.mutable = ptr_info.mutable and peer_info.mutable;32330 ptr_info.flags.is_const = ptr_info.flags.is_const or peer_info.flags.is_const;
32286 ptr_info.@"volatile" = ptr_info.@"volatile" or peer_info.@"volatile";32331 ptr_info.flags.is_volatile = ptr_info.flags.is_volatile or peer_info.flags.is_volatile;
3228732332
32288 const peer_sentinel: ?Value = switch (peer_info.size) {32333 const peer_sentinel: InternPool.Index = switch (peer_info.flags.size) {
32289 .One => switch (peer_info.pointee_type.zigTypeTag(mod)) {32334 .One => switch (mod.intern_pool.indexToKey(peer_info.child)) {
32290 .Array => peer_info.pointee_type.sentinel(mod),32335 .array_type => |array_type| array_type.sentinel,
32291 else => null,32336 else => .none,
32292 },32337 },
32293 .Many, .Slice => peer_info.sentinel,32338 .Many, .Slice => peer_info.sentinel,
32294 .C => unreachable,32339 .C => unreachable,
32295 };32340 };
3229632341
32297 const cur_sentinel: ?Value = switch (ptr_info.size) {32342 const cur_sentinel: InternPool.Index = switch (ptr_info.flags.size) {
32298 .One => switch (ptr_info.pointee_type.zigTypeTag(mod)) {32343 .One => switch (mod.intern_pool.indexToKey(ptr_info.child)) {
32299 .Array => ptr_info.pointee_type.sentinel(mod),32344 .array_type => |array_type| array_type.sentinel,
32300 else => null,32345 else => .none,
32301 },32346 },
32302 .Many, .Slice => ptr_info.sentinel,32347 .Many, .Slice => ptr_info.sentinel,
32303 .C => unreachable,32348 .C => unreachable,
32304 };32349 };
3230532350
32306 // We abstract array handling slightly so that tuple pointers can work like array pointers32351 // We abstract array handling slightly so that tuple pointers can work like array pointers
32307 const peer_pointee_array = sema.typeIsArrayLike(peer_info.pointee_type);32352 const peer_pointee_array = sema.typeIsArrayLike(peer_info.child.toType());
32308 const cur_pointee_array = sema.typeIsArrayLike(ptr_info.pointee_type);32353 const cur_pointee_array = sema.typeIsArrayLike(ptr_info.child.toType());
3230932354
32310 // This switch is just responsible for deciding the size and pointee (not including32355 // This switch is just responsible for deciding the size and pointee (not including
32311 // single-pointer array sentinel).32356 // single-pointer array sentinel).
32312 good: {32357 good: {
32313 switch (peer_info.size) {32358 switch (peer_info.flags.size) {
32314 .One => switch (ptr_info.size) {32359 .One => switch (ptr_info.flags.size) {
32315 .One => {32360 .One => {
32316 if (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.pointee_type, peer_info.pointee_type)) |pointee| {32361 if (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.child.toType(), peer_info.child.toType())) |pointee| {
32317 ptr_info.pointee_type = pointee;32362 ptr_info.child = pointee.toIntern();
32318 break :good;32363 break :good;
32319 }32364 }
3232032365
...@@ -32324,29 +32369,29 @@ fn resolvePeerTypesInner(...@@ -32324,29 +32369,29 @@ fn resolvePeerTypesInner(
32324 if (try sema.resolvePairInMemoryCoercible(block, src, cur_arr.elem_ty, peer_arr.elem_ty)) |elem_ty| {32369 if (try sema.resolvePairInMemoryCoercible(block, src, cur_arr.elem_ty, peer_arr.elem_ty)) |elem_ty| {
32325 // *[n:x]T + *[n:y]T = *[n]T32370 // *[n:x]T + *[n:y]T = *[n]T
32326 if (cur_arr.len == peer_arr.len) {32371 if (cur_arr.len == peer_arr.len) {
32327 ptr_info.pointee_type = try mod.arrayType(.{32372 ptr_info.child = (try mod.arrayType(.{
32328 .len = cur_arr.len,32373 .len = cur_arr.len,
32329 .child = elem_ty.toIntern(),32374 .child = elem_ty.toIntern(),
32330 });32375 })).toIntern();
32331 break :good;32376 break :good;
32332 }32377 }
32333 // *[a]T + *[b]T = []T32378 // *[a]T + *[b]T = []T
32334 ptr_info.size = .Slice;32379 ptr_info.flags.size = .Slice;
32335 ptr_info.pointee_type = elem_ty;32380 ptr_info.child = elem_ty.toIntern();
32336 break :good;32381 break :good;
32337 }32382 }
3233832383
32339 if (peer_arr.elem_ty.toIntern() == .noreturn_type) {32384 if (peer_arr.elem_ty.toIntern() == .noreturn_type) {
32340 // *struct{} + *[a]T = []T32385 // *struct{} + *[a]T = []T
32341 ptr_info.size = .Slice;32386 ptr_info.flags.size = .Slice;
32342 ptr_info.pointee_type = cur_arr.elem_ty;32387 ptr_info.child = cur_arr.elem_ty.toIntern();
32343 break :good;32388 break :good;
32344 }32389 }
3234532390
32346 if (cur_arr.elem_ty.toIntern() == .noreturn_type) {32391 if (cur_arr.elem_ty.toIntern() == .noreturn_type) {
32347 // *[a]T + *struct{} = []T32392 // *[a]T + *struct{} = []T
32348 ptr_info.size = .Slice;32393 ptr_info.flags.size = .Slice;
32349 ptr_info.pointee_type = peer_arr.elem_ty;32394 ptr_info.child = peer_arr.elem_ty.toIntern();
32350 break :good;32395 break :good;
32351 }32396 }
3235232397
...@@ -32355,8 +32400,8 @@ fn resolvePeerTypesInner(...@@ -32355,8 +32400,8 @@ fn resolvePeerTypesInner(
32355 .Many => {32400 .Many => {
32356 // Only works for *[n]T + [*]T -> [*]T32401 // Only works for *[n]T + [*]T -> [*]T
32357 const arr = peer_pointee_array orelse return generic_err;32402 const arr = peer_pointee_array orelse return generic_err;
32358 if (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.pointee_type, arr.elem_ty)) |pointee| {32403 if (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.child.toType(), arr.elem_ty)) |pointee| {
32359 ptr_info.pointee_type = pointee;32404 ptr_info.child = pointee.toIntern();
32360 break :good;32405 break :good;
32361 }32406 }
32362 if (arr.elem_ty.toIntern() == .noreturn_type) {32407 if (arr.elem_ty.toIntern() == .noreturn_type) {
...@@ -32368,8 +32413,8 @@ fn resolvePeerTypesInner(...@@ -32368,8 +32413,8 @@ fn resolvePeerTypesInner(
32368 .Slice => {32413 .Slice => {
32369 // Only works for *[n]T + []T -> []T32414 // Only works for *[n]T + []T -> []T
32370 const arr = peer_pointee_array orelse return generic_err;32415 const arr = peer_pointee_array orelse return generic_err;
32371 if (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.pointee_type, arr.elem_ty)) |pointee| {32416 if (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.child.toType(), arr.elem_ty)) |pointee| {
32372 ptr_info.pointee_type = pointee;32417 ptr_info.child = pointee.toIntern();
32373 break :good;32418 break :good;
32374 }32419 }
32375 if (arr.elem_ty.toIntern() == .noreturn_type) {32420 if (arr.elem_ty.toIntern() == .noreturn_type) {
...@@ -32380,26 +32425,26 @@ fn resolvePeerTypesInner(...@@ -32380,26 +32425,26 @@ fn resolvePeerTypesInner(
32380 },32425 },
32381 .C => unreachable,32426 .C => unreachable,
32382 },32427 },
32383 .Many => switch (ptr_info.size) {32428 .Many => switch (ptr_info.flags.size) {
32384 .One => {32429 .One => {
32385 // Only works for [*]T + *[n]T -> [*]T32430 // Only works for [*]T + *[n]T -> [*]T
32386 const arr = cur_pointee_array orelse return generic_err;32431 const arr = cur_pointee_array orelse return generic_err;
32387 if (try sema.resolvePairInMemoryCoercible(block, src, arr.elem_ty, peer_info.pointee_type)) |pointee| {32432 if (try sema.resolvePairInMemoryCoercible(block, src, arr.elem_ty, peer_info.child.toType())) |pointee| {
32388 ptr_info.size = .Many;32433 ptr_info.flags.size = .Many;
32389 ptr_info.pointee_type = pointee;32434 ptr_info.child = pointee.toIntern();
32390 break :good;32435 break :good;
32391 }32436 }
32392 if (arr.elem_ty.toIntern() == .noreturn_type) {32437 if (arr.elem_ty.toIntern() == .noreturn_type) {
32393 // [*]T + *struct{} -> [*]T32438 // [*]T + *struct{} -> [*]T
32394 ptr_info.size = .Many;32439 ptr_info.flags.size = .Many;
32395 ptr_info.pointee_type = peer_info.pointee_type;32440 ptr_info.child = peer_info.child;
32396 break :good;32441 break :good;
32397 }32442 }
32398 return generic_err;32443 return generic_err;
32399 },32444 },
32400 .Many => {32445 .Many => {
32401 if (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.pointee_type, peer_info.pointee_type)) |pointee| {32446 if (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.child.toType(), peer_info.child.toType())) |pointee| {
32402 ptr_info.pointee_type = pointee;32447 ptr_info.child = pointee.toIntern();
32403 break :good;32448 break :good;
32404 }32449 }
32405 return generic_err;32450 return generic_err;
...@@ -32413,28 +32458,28 @@ fn resolvePeerTypesInner(...@@ -32413,28 +32458,28 @@ fn resolvePeerTypesInner(
32413 } };32458 } };
32414 }32459 }
32415 // Okay, then works for [*]T + "[]T" -> [*]T32460 // Okay, then works for [*]T + "[]T" -> [*]T
32416 if (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.pointee_type, peer_info.pointee_type)) |pointee| {32461 if (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.child.toType(), peer_info.child.toType())) |pointee| {
32417 ptr_info.size = .Many;32462 ptr_info.flags.size = .Many;
32418 ptr_info.pointee_type = pointee;32463 ptr_info.child = pointee.toIntern();
32419 break :good;32464 break :good;
32420 }32465 }
32421 return generic_err;32466 return generic_err;
32422 },32467 },
32423 .C => unreachable,32468 .C => unreachable,
32424 },32469 },
32425 .Slice => switch (ptr_info.size) {32470 .Slice => switch (ptr_info.flags.size) {
32426 .One => {32471 .One => {
32427 // Only works for []T + *[n]T -> []T32472 // Only works for []T + *[n]T -> []T
32428 const arr = cur_pointee_array orelse return generic_err;32473 const arr = cur_pointee_array orelse return generic_err;
32429 if (try sema.resolvePairInMemoryCoercible(block, src, arr.elem_ty, peer_info.pointee_type)) |pointee| {32474 if (try sema.resolvePairInMemoryCoercible(block, src, arr.elem_ty, peer_info.child.toType())) |pointee| {
32430 ptr_info.size = .Slice;32475 ptr_info.flags.size = .Slice;
32431 ptr_info.pointee_type = pointee;32476 ptr_info.child = pointee.toIntern();
32432 break :good;32477 break :good;
32433 }32478 }
32434 if (arr.elem_ty.toIntern() == .noreturn_type) {32479 if (arr.elem_ty.toIntern() == .noreturn_type) {
32435 // []T + *struct{} -> []T32480 // []T + *struct{} -> []T
32436 ptr_info.size = .Slice;32481 ptr_info.flags.size = .Slice;
32437 ptr_info.pointee_type = peer_info.pointee_type;32482 ptr_info.child = peer_info.child;
32438 break :good;32483 break :good;
32439 }32484 }
32440 return generic_err;32485 return generic_err;
...@@ -32444,8 +32489,8 @@ fn resolvePeerTypesInner(...@@ -32444,8 +32489,8 @@ fn resolvePeerTypesInner(
32444 return generic_err;32489 return generic_err;
32445 },32490 },
32446 .Slice => {32491 .Slice => {
32447 if (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.pointee_type, peer_info.pointee_type)) |pointee| {32492 if (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.child.toType(), peer_info.child.toType())) |pointee| {
32448 ptr_info.pointee_type = pointee;32493 ptr_info.child = pointee.toIntern();
32449 break :good;32494 break :good;
32450 }32495 }
32451 return generic_err;32496 return generic_err;
...@@ -32456,40 +32501,43 @@ fn resolvePeerTypesInner(...@@ -32456,40 +32501,43 @@ fn resolvePeerTypesInner(
32456 }32501 }
32457 }32502 }
3245832503
32459 const sentinel_ty = if (ptr_info.size == .One and ptr_info.pointee_type.zigTypeTag(mod) == .Array) blk: {32504 const sentinel_ty = switch (ptr_info.flags.size) {
32460 break :blk ptr_info.pointee_type.childType(mod);32505 .One => switch (mod.intern_pool.indexToKey(ptr_info.child)) {
32461 } else ptr_info.pointee_type;32506 .array_type => |array_type| array_type.child,
3246232507 else => ptr_info.child,
32463 // TODO: once InternPool is in, we need to cast the sentinels to sentinel_ty32508 },
32509 .Many, .Slice, .C => ptr_info.child,
32510 };
3246432511
32465 sentinel: {32512 sentinel: {
32466 no_sentinel: {32513 no_sentinel: {
32467 if (peer_sentinel == null) break :no_sentinel;32514 if (peer_sentinel == .none) break :no_sentinel;
32468 if (cur_sentinel == null) break :no_sentinel;32515 if (cur_sentinel == .none) break :no_sentinel;
32469 const peer_sent_coerced = try mod.getCoerced(peer_sentinel.?, sentinel_ty);32516 const peer_sent_coerced = try mod.intern_pool.getCoerced(sema.gpa, peer_sentinel, sentinel_ty);
32470 const cur_sent_coerced = try mod.getCoerced(cur_sentinel.?, sentinel_ty);32517 const cur_sent_coerced = try mod.intern_pool.getCoerced(sema.gpa, cur_sentinel, sentinel_ty);
32471 if (!peer_sent_coerced.eql(cur_sent_coerced, sentinel_ty, mod)) break :no_sentinel;32518 if (peer_sent_coerced != cur_sent_coerced) break :no_sentinel;
32472 // Sentinels match32519 // Sentinels match
32473 if (ptr_info.size == .One) {32520 if (ptr_info.flags.size == .One) switch (mod.intern_pool.indexToKey(ptr_info.child)) {
32474 assert(ptr_info.pointee_type.zigTypeTag(mod) == .Array);32521 .array_type => |array_type| ptr_info.child = (try mod.arrayType(.{
32475 ptr_info.pointee_type = try mod.arrayType(.{32522 .len = array_type.len,
32476 .len = ptr_info.pointee_type.arrayLen(mod),32523 .child = array_type.child,
32477 .child = ptr_info.pointee_type.childType(mod).toIntern(),32524 .sentinel = cur_sent_coerced,
32478 .sentinel = cur_sent_coerced.toIntern(),32525 })).toIntern(),
32479 });32526 else => unreachable,
32480 } else {32527 } else {
32481 ptr_info.sentinel = cur_sent_coerced;32528 ptr_info.sentinel = cur_sent_coerced;
32482 }32529 }
32483 break :sentinel;32530 break :sentinel;
32484 }32531 }
32485 // Clear existing sentinel32532 // Clear existing sentinel
32486 ptr_info.sentinel = null;32533 ptr_info.sentinel = .none;
32487 if (ptr_info.pointee_type.zigTypeTag(mod) == .Array) {32534 switch (mod.intern_pool.indexToKey(ptr_info.child)) {
32488 ptr_info.pointee_type = try mod.arrayType(.{32535 .array_type => |array_type| ptr_info.child = (try mod.arrayType(.{
32489 .len = ptr_info.pointee_type.arrayLen(mod),32536 .len = array_type.len,
32490 .child = ptr_info.pointee_type.childType(mod).toIntern(),32537 .child = array_type.child,
32491 .sentinel = .none,32538 .sentinel = .none,
32492 });32539 })).toIntern(),
32540 else => {},
32493 }32541 }
32494 }32542 }
3249532543
...@@ -32500,17 +32548,22 @@ fn resolvePeerTypesInner(...@@ -32500,17 +32548,22 @@ fn resolvePeerTypesInner(
32500 // &.{} and &.{}, we'll currently have a pointer type of `*[0]noreturn` - we wanted to32548 // &.{} and &.{}, we'll currently have a pointer type of `*[0]noreturn` - we wanted to
32501 // coerce the empty struct to a specific type, but no peer provided one. We need to32549 // coerce the empty struct to a specific type, but no peer provided one. We need to
32502 // detect this case and emit an error.32550 // detect this case and emit an error.
32503 const pointee = opt_ptr_info.?.pointee_type;32551 const pointee = opt_ptr_info.?.child;
32504 if (pointee.toIntern() == .noreturn_type or32552 switch (pointee) {
32505 (pointee.zigTypeTag(mod) == .Array and pointee.childType(mod).toIntern() == .noreturn_type))32553 .noreturn_type => return .{ .conflict = .{
32506 {
32507 return .{ .conflict = .{
32508 .peer_idx_a = first_idx,32554 .peer_idx_a = first_idx,
32509 .peer_idx_b = other_idx,32555 .peer_idx_b = other_idx,
32510 } };32556 } },
32557 else => switch (mod.intern_pool.indexToKey(pointee)) {
32558 .array_type => |array_type| if (array_type.child == .noreturn_type) return .{ .conflict = .{
32559 .peer_idx_a = first_idx,
32560 .peer_idx_b = other_idx,
32561 } },
32562 else => {},
32563 },
32511 }32564 }
3251232565
32513 return .{ .success = try Type.ptr(sema.arena, mod, opt_ptr_info.?) };32566 return .{ .success = try mod.ptrType(opt_ptr_info.?) };
32514 },32567 },
3251532568
32516 .func => {32569 .func => {
...@@ -34158,7 +34211,7 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void...@@ -34158,7 +34211,7 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void
34158 }34211 }
34159 gop.value_ptr.* = .{34212 gop.value_ptr.* = .{
34160 .ty = Type.noreturn,34213 .ty = Type.noreturn,
34161 .abi_align = 0,34214 .abi_align = .none,
34162 .default_val = .none,34215 .default_val = .none,
34163 .is_comptime = is_comptime,34216 .is_comptime = is_comptime,
34164 .offset = undefined,34217 .offset = undefined,
...@@ -34695,7 +34748,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {...@@ -34695,7 +34748,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
3469534748
34696 gop.value_ptr.* = .{34749 gop.value_ptr.* = .{
34697 .ty = field_ty,34750 .ty = field_ty,
34698 .abi_align = 0,34751 .abi_align = .none,
34699 };34752 };
3470034753
34701 if (align_ref != .none) {34754 if (align_ref != .none) {
...@@ -34711,7 +34764,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {...@@ -34711,7 +34764,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
34711 else => |e| return e,34764 else => |e| return e,
34712 };34765 };
34713 } else {34766 } else {
34714 gop.value_ptr.abi_align = 0;34767 gop.value_ptr.abi_align = .none;
34715 }34768 }
34716 }34769 }
3471734770
...@@ -35335,15 +35388,19 @@ fn analyzeComptimeAlloc(...@@ -35335,15 +35388,19 @@ fn analyzeComptimeAlloc(
35335 sema: *Sema,35388 sema: *Sema,
35336 block: *Block,35389 block: *Block,
35337 var_type: Type,35390 var_type: Type,
35338 alignment: u32,35391 alignment: Alignment,
35339) CompileError!Air.Inst.Ref {35392) CompileError!Air.Inst.Ref {
35393 const mod = sema.mod;
35394
35340 // Needed to make an anon decl with type `var_type` (the `finish()` call below).35395 // Needed to make an anon decl with type `var_type` (the `finish()` call below).
35341 _ = try sema.typeHasOnePossibleValue(var_type);35396 _ = try sema.typeHasOnePossibleValue(var_type);
3534235397
35343 const ptr_type = try Type.ptr(sema.arena, sema.mod, .{35398 const ptr_type = try mod.ptrType(.{
35344 .pointee_type = var_type,35399 .child = var_type.toIntern(),
35345 .@"addrspace" = target_util.defaultAddressSpace(sema.mod.getTarget(), .global_constant),35400 .flags = .{
35346 .@"align" = alignment,35401 .alignment = alignment,
35402 .address_space = target_util.defaultAddressSpace(mod.getTarget(), .global_constant),
35403 },
35347 });35404 });
3534835405
35349 var anon_decl = try block.startAnonDecl();35406 var anon_decl = try block.startAnonDecl();
...@@ -35354,15 +35411,15 @@ fn analyzeComptimeAlloc(...@@ -35354,15 +35411,15 @@ fn analyzeComptimeAlloc(
35354 // There will be stores before the first load, but they may be to sub-elements or35411 // There will be stores before the first load, but they may be to sub-elements or
35355 // sub-fields. So we need to initialize with undef to allow the mechanism to expand35412 // sub-fields. So we need to initialize with undef to allow the mechanism to expand
35356 // into fields/elements and have those overridden with stored values.35413 // into fields/elements and have those overridden with stored values.
35357 (try sema.mod.intern(.{ .undef = var_type.toIntern() })).toValue(),35414 (try mod.intern(.{ .undef = var_type.toIntern() })).toValue(),
35358 alignment,35415 alignment,
35359 );35416 );
35360 const decl = sema.mod.declPtr(decl_index);35417 const decl = mod.declPtr(decl_index);
35361 decl.@"align" = alignment;35418 decl.alignment = alignment;
3536235419
35363 try sema.comptime_mutable_decls.append(decl_index);35420 try sema.comptime_mutable_decls.append(decl_index);
35364 try sema.mod.declareDeclDependency(sema.owner_decl_index, decl_index);35421 try mod.declareDeclDependency(sema.owner_decl_index, decl_index);
35365 return sema.addConstant(ptr_type, (try sema.mod.intern(.{ .ptr = .{35422 return sema.addConstant(ptr_type, (try mod.intern(.{ .ptr = .{
35366 .ty = ptr_type.toIntern(),35423 .ty = ptr_type.toIntern(),
35367 .addr = .{ .mut_decl = .{35424 .addr = .{ .mut_decl = .{
35368 .decl = decl_index,35425 .decl = decl_index,
...@@ -35747,14 +35804,10 @@ fn typeAbiAlignment(sema: *Sema, ty: Type) CompileError!u32 {...@@ -35747,14 +35804,10 @@ fn typeAbiAlignment(sema: *Sema, ty: Type) CompileError!u32 {
35747/// Not valid to call for packed unions.35804/// Not valid to call for packed unions.
35748/// Keep implementation in sync with `Module.Union.Field.normalAlignment`.35805/// Keep implementation in sync with `Module.Union.Field.normalAlignment`.
35749fn unionFieldAlignment(sema: *Sema, field: Module.Union.Field) !u32 {35806fn unionFieldAlignment(sema: *Sema, field: Module.Union.Field) !u32 {
35750 const mod = sema.mod;35807 return @intCast(u32, if (field.ty.isNoReturn(sema.mod))
35751 if (field.ty.zigTypeTag(mod) == .NoReturn) {35808 0
35752 return @as(u32, 0);35809 else
35753 } else if (field.abi_align == 0) {35810 field.abi_align.toByteUnitsOptional() orelse try sema.typeAbiAlignment(field.ty));
35754 return sema.typeAbiAlignment(field.ty);
35755 } else {
35756 return field.abi_align;
35757 }
35758}35811}
3575935812
35760/// Synchronize logic with `Type.isFnOrHasRuntimeBits`.35813/// Synchronize logic with `Type.isFnOrHasRuntimeBits`.
...@@ -36405,16 +36458,16 @@ fn elemPtrType(sema: *Sema, ptr_ty: Type, offset: ?usize) !Type {...@@ -36405,16 +36458,16 @@ fn elemPtrType(sema: *Sema, ptr_ty: Type, offset: ?usize) !Type {
36405 const mod = sema.mod;36458 const mod = sema.mod;
36406 const ptr_info = ptr_ty.ptrInfo(mod);36459 const ptr_info = ptr_ty.ptrInfo(mod);
36407 const elem_ty = ptr_ty.elemType2(mod);36460 const elem_ty = ptr_ty.elemType2(mod);
36408 const allow_zero = ptr_info.@"allowzero" and (offset orelse 0) == 0;36461 const is_allowzero = ptr_info.flags.is_allowzero and (offset orelse 0) == 0;
36409 const parent_ty = ptr_ty.childType(mod);36462 const parent_ty = ptr_ty.childType(mod);
3641036463
36411 const VI = Type.Payload.Pointer.Data.VectorIndex;36464 const VI = InternPool.Key.PtrType.VectorIndex;
3641236465
36413 const vector_info: struct {36466 const vector_info: struct {
36414 host_size: u16 = 0,36467 host_size: u16 = 0,
36415 alignment: u32 = 0,36468 alignment: u32 = 0,
36416 vector_index: VI = .none,36469 vector_index: VI = .none,
36417 } = if (parent_ty.isVector(mod) and ptr_info.size == .One) blk: {36470 } = if (parent_ty.isVector(mod) and ptr_info.flags.size == .One) blk: {
36418 const elem_bits = elem_ty.bitSize(mod);36471 const elem_bits = elem_ty.bitSize(mod);
36419 if (elem_bits == 0) break :blk .{};36472 if (elem_bits == 0) break :blk .{};
36420 const is_packed = elem_bits < 8 or !std.math.isPowerOfTwo(elem_bits);36473 const is_packed = elem_bits < 8 or !std.math.isPowerOfTwo(elem_bits);
...@@ -36422,17 +36475,17 @@ fn elemPtrType(sema: *Sema, ptr_ty: Type, offset: ?usize) !Type {...@@ -36422,17 +36475,17 @@ fn elemPtrType(sema: *Sema, ptr_ty: Type, offset: ?usize) !Type {
3642236475
36423 break :blk .{36476 break :blk .{
36424 .host_size = @intCast(u16, parent_ty.arrayLen(mod)),36477 .host_size = @intCast(u16, parent_ty.arrayLen(mod)),
36425 .alignment = @intCast(u16, parent_ty.abiAlignment(mod)),36478 .alignment = @intCast(u32, parent_ty.abiAlignment(mod)),
36426 .vector_index = if (offset) |some| @enumFromInt(VI, some) else .runtime,36479 .vector_index = if (offset) |some| @enumFromInt(VI, some) else .runtime,
36427 };36480 };
36428 } else .{};36481 } else .{};
3642936482
36430 const alignment: u32 = a: {36483 const alignment: Alignment = a: {
36431 // Calculate the new pointer alignment.36484 // Calculate the new pointer alignment.
36432 if (ptr_info.@"align" == 0) {36485 if (ptr_info.flags.alignment == .none) {
36433 if (vector_info.alignment != 0) break :a vector_info.alignment;36486 if (vector_info.alignment != 0) break :a Alignment.fromNonzeroByteUnits(vector_info.alignment);
36434 // ABI-aligned pointer. Any pointer arithmetic maintains the same ABI-alignedness.36487 // ABI-aligned pointer. Any pointer arithmetic maintains the same ABI-alignedness.
36435 break :a 0;36488 break :a .none;
36436 }36489 }
36437 // If the addend is not a comptime-known value we can still count on36490 // If the addend is not a comptime-known value we can still count on
36438 // it being a multiple of the type size.36491 // it being a multiple of the type size.
...@@ -36442,18 +36495,27 @@ fn elemPtrType(sema: *Sema, ptr_ty: Type, offset: ?usize) !Type {...@@ -36442,18 +36495,27 @@ fn elemPtrType(sema: *Sema, ptr_ty: Type, offset: ?usize) !Type {
36442 // The resulting pointer is aligned to the lcd between the offset (an36495 // The resulting pointer is aligned to the lcd between the offset (an
36443 // arbitrary number) and the alignment factor (always a power of two,36496 // arbitrary number) and the alignment factor (always a power of two,
36444 // non zero).36497 // non zero).
36445 const new_align = @as(u32, 1) << @intCast(u5, @ctz(addend | ptr_info.@"align"));36498 const new_align = @enumFromInt(Alignment, @min(
36499 @ctz(addend),
36500 @intFromEnum(ptr_info.flags.alignment),
36501 ));
36502 assert(new_align != .none);
36446 break :a new_align;36503 break :a new_align;
36447 };36504 };
36448 return try Type.ptr(sema.arena, sema.mod, .{36505 return mod.ptrType(.{
36449 .pointee_type = elem_ty,36506 .child = elem_ty.toIntern(),
36450 .mutable = ptr_info.mutable,36507 .flags = .{
36451 .@"addrspace" = ptr_info.@"addrspace",36508 .alignment = alignment,
36452 .@"allowzero" = allow_zero,36509 .is_const = ptr_info.flags.is_const,
36453 .@"volatile" = ptr_info.@"volatile",36510 .is_volatile = ptr_info.flags.is_volatile,
36454 .@"align" = alignment,36511 .is_allowzero = is_allowzero,
36455 .host_size = vector_info.host_size,36512 .address_space = ptr_info.flags.address_space,
36456 .vector_index = vector_info.vector_index,36513 .vector_index = vector_info.vector_index,
36514 },
36515 .packed_offset = .{
36516 .host_size = vector_info.host_size,
36517 .bit_offset = 0,
36518 },
36457 });36519 });
36458}36520}
3645936521
src/arch/wasm/CodeGen.zig+15-15
...@@ -2308,25 +2308,25 @@ fn airStore(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void...@@ -2308,25 +2308,25 @@ fn airStore(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void
2308 const ptr_info = ptr_ty.ptrInfo(mod);2308 const ptr_info = ptr_ty.ptrInfo(mod);
2309 const ty = ptr_ty.childType(mod);2309 const ty = ptr_ty.childType(mod);
23102310
2311 if (ptr_info.host_size == 0) {2311 if (ptr_info.packed_offset.host_size == 0) {
2312 try func.store(lhs, rhs, ty, 0);2312 try func.store(lhs, rhs, ty, 0);
2313 } else {2313 } else {
2314 // at this point we have a non-natural alignment, we must2314 // at this point we have a non-natural alignment, we must
2315 // load the value, and then shift+or the rhs into the result location.2315 // load the value, and then shift+or the rhs into the result location.
2316 const int_elem_ty = try mod.intType(.unsigned, ptr_info.host_size * 8);2316 const int_elem_ty = try mod.intType(.unsigned, ptr_info.packed_offset.host_size * 8);
23172317
2318 if (isByRef(int_elem_ty, mod)) {2318 if (isByRef(int_elem_ty, mod)) {
2319 return func.fail("TODO: airStore for pointers to bitfields with backing type larger than 64bits", .{});2319 return func.fail("TODO: airStore for pointers to bitfields with backing type larger than 64bits", .{});
2320 }2320 }
23212321
2322 var mask = @intCast(u64, (@as(u65, 1) << @intCast(u7, ty.bitSize(mod))) - 1);2322 var mask = @intCast(u64, (@as(u65, 1) << @intCast(u7, ty.bitSize(mod))) - 1);
2323 mask <<= @intCast(u6, ptr_info.bit_offset);2323 mask <<= @intCast(u6, ptr_info.packed_offset.bit_offset);
2324 mask ^= ~@as(u64, 0);2324 mask ^= ~@as(u64, 0);
2325 const shift_val = if (ptr_info.host_size <= 4)2325 const shift_val = if (ptr_info.packed_offset.host_size <= 4)
2326 WValue{ .imm32 = ptr_info.bit_offset }2326 WValue{ .imm32 = ptr_info.packed_offset.bit_offset }
2327 else2327 else
2328 WValue{ .imm64 = ptr_info.bit_offset };2328 WValue{ .imm64 = ptr_info.packed_offset.bit_offset };
2329 const mask_val = if (ptr_info.host_size <= 4)2329 const mask_val = if (ptr_info.packed_offset.host_size <= 4)
2330 WValue{ .imm32 = @truncate(u32, mask) }2330 WValue{ .imm32 = @truncate(u32, mask) }
2331 else2331 else
2332 WValue{ .imm64 = mask };2332 WValue{ .imm64 = mask };
...@@ -2335,7 +2335,7 @@ fn airStore(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void...@@ -2335,7 +2335,7 @@ fn airStore(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void
2335 const loaded = try func.load(lhs, int_elem_ty, 0);2335 const loaded = try func.load(lhs, int_elem_ty, 0);
2336 const anded = try func.binOp(loaded, mask_val, int_elem_ty, .@"and");2336 const anded = try func.binOp(loaded, mask_val, int_elem_ty, .@"and");
2337 const extended_value = try func.intcast(rhs, ty, int_elem_ty);2337 const extended_value = try func.intcast(rhs, ty, int_elem_ty);
2338 const shifted_value = if (ptr_info.bit_offset > 0) shifted: {2338 const shifted_value = if (ptr_info.packed_offset.bit_offset > 0) shifted: {
2339 break :shifted try func.binOp(extended_value, shift_val, int_elem_ty, .shl);2339 break :shifted try func.binOp(extended_value, shift_val, int_elem_ty, .shl);
2340 } else extended_value;2340 } else extended_value;
2341 const result = try func.binOp(anded, shifted_value, int_elem_ty, .@"or");2341 const result = try func.binOp(anded, shifted_value, int_elem_ty, .@"or");
...@@ -2468,18 +2468,18 @@ fn airLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -2468,18 +2468,18 @@ fn airLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
2468 break :result new_local;2468 break :result new_local;
2469 }2469 }
24702470
2471 if (ptr_info.host_size == 0) {2471 if (ptr_info.packed_offset.host_size == 0) {
2472 const stack_loaded = try func.load(operand, ty, 0);2472 const stack_loaded = try func.load(operand, ty, 0);
2473 break :result try stack_loaded.toLocal(func, ty);2473 break :result try stack_loaded.toLocal(func, ty);
2474 }2474 }
24752475
2476 // at this point we have a non-natural alignment, we must2476 // at this point we have a non-natural alignment, we must
2477 // shift the value to obtain the correct bit.2477 // shift the value to obtain the correct bit.
2478 const int_elem_ty = try mod.intType(.unsigned, ptr_info.host_size * 8);2478 const int_elem_ty = try mod.intType(.unsigned, ptr_info.packed_offset.host_size * 8);
2479 const shift_val = if (ptr_info.host_size <= 4)2479 const shift_val = if (ptr_info.packed_offset.host_size <= 4)
2480 WValue{ .imm32 = ptr_info.bit_offset }2480 WValue{ .imm32 = ptr_info.packed_offset.bit_offset }
2481 else if (ptr_info.host_size <= 8)2481 else if (ptr_info.packed_offset.host_size <= 8)
2482 WValue{ .imm64 = ptr_info.bit_offset }2482 WValue{ .imm64 = ptr_info.packed_offset.bit_offset }
2483 else2483 else
2484 return func.fail("TODO: airLoad where ptr to bitfield exceeds 64 bits", .{});2484 return func.fail("TODO: airLoad where ptr to bitfield exceeds 64 bits", .{});
24852485
...@@ -3699,7 +3699,7 @@ fn structFieldPtr(...@@ -3699,7 +3699,7 @@ fn structFieldPtr(
3699 const offset = switch (struct_ty.containerLayout(mod)) {3699 const offset = switch (struct_ty.containerLayout(mod)) {
3700 .Packed => switch (struct_ty.zigTypeTag(mod)) {3700 .Packed => switch (struct_ty.zigTypeTag(mod)) {
3701 .Struct => offset: {3701 .Struct => offset: {
3702 if (result_ty.ptrInfo(mod).host_size != 0) {3702 if (result_ty.ptrInfo(mod).packed_offset.host_size != 0) {
3703 break :offset @as(u32, 0);3703 break :offset @as(u32, 0);
3704 }3704 }
3705 break :offset struct_ty.packedStructFieldByteOffset(index, mod);3705 break :offset struct_ty.packedStructFieldByteOffset(index, mod);
src/arch/wasm/abi.zig+2-2
...@@ -34,8 +34,8 @@ pub fn classifyType(ty: Type, mod: *Module) [2]Class {...@@ -34,8 +34,8 @@ pub fn classifyType(ty: Type, mod: *Module) [2]Class {
34 if (ty.structFieldCount(mod) > 1) return memory;34 if (ty.structFieldCount(mod) > 1) return memory;
35 // When the struct's alignment is non-natural35 // When the struct's alignment is non-natural
36 const field = ty.structFields(mod).values()[0];36 const field = ty.structFields(mod).values()[0];
37 if (field.abi_align != 0) {37 if (field.abi_align != .none) {
38 if (field.abi_align > field.ty.abiAlignment(mod)) {38 if (field.abi_align.toByteUnitsOptional().? > field.ty.abiAlignment(mod)) {
39 return memory;39 return memory;
40 }40 }
41 }41 }
src/arch/x86_64/CodeGen.zig+10-10
...@@ -694,7 +694,7 @@ pub fn generate(...@@ -694,7 +694,7 @@ pub fn generate(
694 FrameAlloc.init(.{694 FrameAlloc.init(.{
695 .size = 0,695 .size = 0,
696 .alignment = if (mod.align_stack_fns.get(module_fn_index)) |set_align_stack|696 .alignment = if (mod.align_stack_fns.get(module_fn_index)) |set_align_stack|
697 set_align_stack.alignment697 @intCast(u32, set_align_stack.alignment.toByteUnitsOptional().?)
698 else698 else
699 1,699 1,
700 }),700 }),
...@@ -5254,12 +5254,12 @@ fn packedLoad(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) Inn...@@ -5254,12 +5254,12 @@ fn packedLoad(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) Inn
5254 const mod = self.bin_file.options.module.?;5254 const mod = self.bin_file.options.module.?;
5255 const ptr_info = ptr_ty.ptrInfo(mod);5255 const ptr_info = ptr_ty.ptrInfo(mod);
52565256
5257 const val_ty = ptr_info.pointee_type;5257 const val_ty = ptr_info.child.toType();
5258 const val_abi_size = @intCast(u32, val_ty.abiSize(mod));5258 const val_abi_size = @intCast(u32, val_ty.abiSize(mod));
5259 const limb_abi_size: u32 = @min(val_abi_size, 8);5259 const limb_abi_size: u32 = @min(val_abi_size, 8);
5260 const limb_abi_bits = limb_abi_size * 8;5260 const limb_abi_bits = limb_abi_size * 8;
5261 const val_byte_off = @intCast(i32, ptr_info.bit_offset / limb_abi_bits * limb_abi_size);5261 const val_byte_off = @intCast(i32, ptr_info.packed_offset.bit_offset / limb_abi_bits * limb_abi_size);
5262 const val_bit_off = ptr_info.bit_offset % limb_abi_bits;5262 const val_bit_off = ptr_info.packed_offset.bit_offset % limb_abi_bits;
5263 const val_extra_bits = self.regExtraBits(val_ty);5263 const val_extra_bits = self.regExtraBits(val_ty);
52645264
5265 if (val_abi_size > 8) return self.fail("TODO implement packed load of {}", .{5265 if (val_abi_size > 8) return self.fail("TODO implement packed load of {}", .{
...@@ -5385,7 +5385,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {...@@ -5385,7 +5385,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
5385 else5385 else
5386 try self.allocRegOrMem(inst, true);5386 try self.allocRegOrMem(inst, true);
53875387
5388 if (ptr_ty.ptrInfo(mod).host_size > 0) {5388 if (ptr_ty.ptrInfo(mod).packed_offset.host_size > 0) {
5389 try self.packedLoad(dst_mcv, ptr_ty, ptr_mcv);5389 try self.packedLoad(dst_mcv, ptr_ty, ptr_mcv);
5390 } else {5390 } else {
5391 try self.load(dst_mcv, ptr_ty, ptr_mcv);5391 try self.load(dst_mcv, ptr_ty, ptr_mcv);
...@@ -5400,12 +5400,12 @@ fn packedStore(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) In...@@ -5400,12 +5400,12 @@ fn packedStore(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) In
5400 const ptr_info = ptr_ty.ptrInfo(mod);5400 const ptr_info = ptr_ty.ptrInfo(mod);
5401 const src_ty = ptr_ty.childType(mod);5401 const src_ty = ptr_ty.childType(mod);
54025402
5403 const limb_abi_size: u16 = @min(ptr_info.host_size, 8);5403 const limb_abi_size: u16 = @min(ptr_info.packed_offset.host_size, 8);
5404 const limb_abi_bits = limb_abi_size * 8;5404 const limb_abi_bits = limb_abi_size * 8;
54055405
5406 const src_bit_size = src_ty.bitSize(mod);5406 const src_bit_size = src_ty.bitSize(mod);
5407 const src_byte_off = @intCast(i32, ptr_info.bit_offset / limb_abi_bits * limb_abi_size);5407 const src_byte_off = @intCast(i32, ptr_info.packed_offset.bit_offset / limb_abi_bits * limb_abi_size);
5408 const src_bit_off = ptr_info.bit_offset % limb_abi_bits;5408 const src_bit_off = ptr_info.packed_offset.bit_offset % limb_abi_bits;
54095409
5410 const ptr_reg = try self.copyToTmpRegister(ptr_ty, ptr_mcv);5410 const ptr_reg = try self.copyToTmpRegister(ptr_ty, ptr_mcv);
5411 const ptr_lock = self.register_manager.lockRegAssumeUnused(ptr_reg);5411 const ptr_lock = self.register_manager.lockRegAssumeUnused(ptr_reg);
...@@ -5516,7 +5516,7 @@ fn airStore(self: *Self, inst: Air.Inst.Index, safety: bool) !void {...@@ -5516,7 +5516,7 @@ fn airStore(self: *Self, inst: Air.Inst.Index, safety: bool) !void {
5516 const ptr_mcv = try self.resolveInst(bin_op.lhs);5516 const ptr_mcv = try self.resolveInst(bin_op.lhs);
5517 const ptr_ty = self.typeOf(bin_op.lhs);5517 const ptr_ty = self.typeOf(bin_op.lhs);
5518 const src_mcv = try self.resolveInst(bin_op.rhs);5518 const src_mcv = try self.resolveInst(bin_op.rhs);
5519 if (ptr_ty.ptrInfo(mod).host_size > 0) {5519 if (ptr_ty.ptrInfo(mod).packed_offset.host_size > 0) {
5520 try self.packedStore(ptr_ty, ptr_mcv, src_mcv);5520 try self.packedStore(ptr_ty, ptr_mcv, src_mcv);
5521 } else {5521 } else {
5522 try self.store(ptr_ty, ptr_mcv, src_mcv);5522 try self.store(ptr_ty, ptr_mcv, src_mcv);
...@@ -5545,7 +5545,7 @@ fn fieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32...@@ -5545,7 +5545,7 @@ fn fieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32
5545 const field_offset = @intCast(i32, switch (container_ty.containerLayout(mod)) {5545 const field_offset = @intCast(i32, switch (container_ty.containerLayout(mod)) {
5546 .Auto, .Extern => container_ty.structFieldOffset(index, mod),5546 .Auto, .Extern => container_ty.structFieldOffset(index, mod),
5547 .Packed => if (container_ty.zigTypeTag(mod) == .Struct and5547 .Packed => if (container_ty.zigTypeTag(mod) == .Struct and
5548 ptr_field_ty.ptrInfo(mod).host_size == 0)5548 ptr_field_ty.ptrInfo(mod).packed_offset.host_size == 0)
5549 container_ty.packedStructFieldByteOffset(index, mod)5549 container_ty.packedStructFieldByteOffset(index, mod)
5550 else5550 else
5551 0,5551 0,
src/arch/x86_64/abi.zig+4-4
...@@ -223,8 +223,8 @@ pub fn classifySystemV(ty: Type, mod: *Module, ctx: Context) [8]Class {...@@ -223,8 +223,8 @@ pub fn classifySystemV(ty: Type, mod: *Module, ctx: Context) [8]Class {
223 var byte_i: usize = 0; // out of 8223 var byte_i: usize = 0; // out of 8
224 const fields = ty.structFields(mod);224 const fields = ty.structFields(mod);
225 for (fields.values()) |field| {225 for (fields.values()) |field| {
226 if (field.abi_align != 0) {226 if (field.abi_align != .none) {
227 if (field.abi_align < field.ty.abiAlignment(mod)) {227 if (field.abi_align.toByteUnitsOptional().? < field.ty.abiAlignment(mod)) {
228 return memory_class;228 return memory_class;
229 }229 }
230 }230 }
...@@ -340,8 +340,8 @@ pub fn classifySystemV(ty: Type, mod: *Module, ctx: Context) [8]Class {...@@ -340,8 +340,8 @@ pub fn classifySystemV(ty: Type, mod: *Module, ctx: Context) [8]Class {
340340
341 const fields = ty.unionFields(mod);341 const fields = ty.unionFields(mod);
342 for (fields.values()) |field| {342 for (fields.values()) |field| {
343 if (field.abi_align != 0) {343 if (field.abi_align != .none) {
344 if (field.abi_align < field.ty.abiAlignment(mod)) {344 if (field.abi_align.toByteUnitsOptional().? < field.ty.abiAlignment(mod)) {
345 return memory_class;345 return memory_class;
346 }346 }
347 }347 }
src/codegen/c.zig+33-28
...@@ -1714,7 +1714,7 @@ pub const DeclGen = struct {...@@ -1714,7 +1714,7 @@ pub const DeclGen = struct {
1714 ty: Type,1714 ty: Type,
1715 name: CValue,1715 name: CValue,
1716 qualifiers: CQualifiers,1716 qualifiers: CQualifiers,
1717 alignment: u32,1717 alignment: u64,
1718 kind: CType.Kind,1718 kind: CType.Kind,
1719 ) error{ OutOfMemory, AnalysisFail }!void {1719 ) error{ OutOfMemory, AnalysisFail }!void {
1720 const mod = dg.module;1720 const mod = dg.module;
...@@ -1733,10 +1733,10 @@ pub const DeclGen = struct {...@@ -1733,10 +1733,10 @@ pub const DeclGen = struct {
1733 const store = &dg.ctypes.set;1733 const store = &dg.ctypes.set;
1734 const mod = dg.module;1734 const mod = dg.module;
17351735
1736 switch (std.math.order(alignas.@"align", alignas.abi)) {1736 switch (alignas.abiOrder()) {
1737 .lt => try w.print("zig_under_align({}) ", .{alignas.getAlign()}),1737 .lt => try w.print("zig_under_align({}) ", .{alignas.toByteUnits()}),
1738 .eq => {},1738 .eq => {},
1739 .gt => try w.print("zig_align({}) ", .{alignas.getAlign()}),1739 .gt => try w.print("zig_align({}) ", .{alignas.toByteUnits()}),
1740 }1740 }
17411741
1742 const trailing =1742 const trailing =
...@@ -1840,7 +1840,7 @@ pub const DeclGen = struct {...@@ -1840,7 +1840,7 @@ pub const DeclGen = struct {
1840 decl.ty,1840 decl.ty,
1841 .{ .decl = decl_index },1841 .{ .decl = decl_index },
1842 CQualifiers.init(.{ .@"const" = variable.is_const }),1842 CQualifiers.init(.{ .@"const" = variable.is_const }),
1843 decl.@"align",1843 @intCast(u32, decl.alignment.toByteUnits(0)),
1844 .complete,1844 .complete,
1845 );1845 );
1846 try fwd_decl_writer.writeAll(";\n");1846 try fwd_decl_writer.writeAll(";\n");
...@@ -2314,10 +2314,10 @@ fn renderAggregateFields(...@@ -2314,10 +2314,10 @@ fn renderAggregateFields(
2314 const fields = cty.fields();2314 const fields = cty.fields();
2315 for (fields) |field| {2315 for (fields) |field| {
2316 try writer.writeByteNTimes(' ', indent + 1);2316 try writer.writeByteNTimes(' ', indent + 1);
2317 switch (std.math.order(field.alignas.@"align", field.alignas.abi)) {2317 switch (field.alignas.abiOrder()) {
2318 .lt => try writer.print("zig_under_align({}) ", .{field.alignas.getAlign()}),2318 .lt => try writer.print("zig_under_align({}) ", .{field.alignas.toByteUnits()}),
2319 .eq => {},2319 .eq => {},
2320 .gt => try writer.print("zig_align({}) ", .{field.alignas.getAlign()}),2320 .gt => try writer.print("zig_align({}) ", .{field.alignas.toByteUnits()}),
2321 }2321 }
2322 const trailing = try renderTypePrefix(.none, store, mod, writer, field.type, .suffix, .{});2322 const trailing = try renderTypePrefix(.none, store, mod, writer, field.type, .suffix, .{});
2323 try writer.print("{}{ }", .{ trailing, fmtIdent(mem.span(field.name)) });2323 try writer.print("{}{ }", .{ trailing, fmtIdent(mem.span(field.name)) });
...@@ -2639,7 +2639,7 @@ pub fn genFunc(f: *Function) !void {...@@ -2639,7 +2639,7 @@ pub fn genFunc(f: *Function) !void {
2639 pub fn lessThan(ctx: @This(), lhs_index: usize, rhs_index: usize) bool {2639 pub fn lessThan(ctx: @This(), lhs_index: usize, rhs_index: usize) bool {
2640 const lhs_ty = ctx.keys[lhs_index];2640 const lhs_ty = ctx.keys[lhs_index];
2641 const rhs_ty = ctx.keys[rhs_index];2641 const rhs_ty = ctx.keys[rhs_index];
2642 return lhs_ty.alignas.getAlign() > rhs_ty.alignas.getAlign();2642 return lhs_ty.alignas.order(rhs_ty.alignas).compare(.gt);
2643 }2643 }
2644 };2644 };
2645 free_locals.sort(SortContext{ .keys = free_locals.keys() });2645 free_locals.sort(SortContext{ .keys = free_locals.keys() });
...@@ -2690,7 +2690,7 @@ pub fn genDecl(o: *Object) !void {...@@ -2690,7 +2690,7 @@ pub fn genDecl(o: *Object) !void {
2690 if (variable.is_weak_linkage) try w.writeAll("zig_weak_linkage ");2690 if (variable.is_weak_linkage) try w.writeAll("zig_weak_linkage ");
2691 if (mod.intern_pool.stringToSliceUnwrap(decl.@"linksection")) |s|2691 if (mod.intern_pool.stringToSliceUnwrap(decl.@"linksection")) |s|
2692 try w.print("zig_linksection(\"{s}\", ", .{s});2692 try w.print("zig_linksection(\"{s}\", ", .{s});
2693 try o.dg.renderTypeAndName(w, tv.ty, decl_c_value, .{}, decl.@"align", .complete);2693 try o.dg.renderTypeAndName(w, tv.ty, decl_c_value, .{}, decl.alignment.toByteUnits(0), .complete);
2694 if (decl.@"linksection" != .none) try w.writeAll(", read, write)");2694 if (decl.@"linksection" != .none) try w.writeAll(", read, write)");
2695 try w.writeAll(" = ");2695 try w.writeAll(" = ");
2696 try o.dg.renderValue(w, tv.ty, variable.init.toValue(), .StaticInitializer);2696 try o.dg.renderValue(w, tv.ty, variable.init.toValue(), .StaticInitializer);
...@@ -2701,14 +2701,14 @@ pub fn genDecl(o: *Object) !void {...@@ -2701,14 +2701,14 @@ pub fn genDecl(o: *Object) !void {
2701 const fwd_decl_writer = o.dg.fwd_decl.writer();2701 const fwd_decl_writer = o.dg.fwd_decl.writer();
27022702
2703 try fwd_decl_writer.writeAll(if (is_global) "zig_extern " else "static ");2703 try fwd_decl_writer.writeAll(if (is_global) "zig_extern " else "static ");
2704 try o.dg.renderTypeAndName(fwd_decl_writer, tv.ty, decl_c_value, Const, decl.@"align", .complete);2704 try o.dg.renderTypeAndName(fwd_decl_writer, tv.ty, decl_c_value, Const, decl.alignment.toByteUnits(0), .complete);
2705 try fwd_decl_writer.writeAll(";\n");2705 try fwd_decl_writer.writeAll(";\n");
27062706
2707 const w = o.writer();2707 const w = o.writer();
2708 if (!is_global) try w.writeAll("static ");2708 if (!is_global) try w.writeAll("static ");
2709 if (mod.intern_pool.stringToSliceUnwrap(decl.@"linksection")) |s|2709 if (mod.intern_pool.stringToSliceUnwrap(decl.@"linksection")) |s|
2710 try w.print("zig_linksection(\"{s}\", ", .{s});2710 try w.print("zig_linksection(\"{s}\", ", .{s});
2711 try o.dg.renderTypeAndName(w, tv.ty, decl_c_value, Const, decl.@"align", .complete);2711 try o.dg.renderTypeAndName(w, tv.ty, decl_c_value, Const, decl.alignment.toByteUnits(0), .complete);
2712 if (decl.@"linksection" != .none) try w.writeAll(", read)");2712 if (decl.@"linksection" != .none) try w.writeAll(", read)");
2713 try w.writeAll(" = ");2713 try w.writeAll(" = ");
2714 try o.dg.renderValue(w, tv.ty, tv.val, .StaticInitializer);2714 try o.dg.renderValue(w, tv.ty, tv.val, .StaticInitializer);
...@@ -3324,7 +3324,7 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3324,7 +3324,7 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
3324 const ptr_ty = f.typeOf(ty_op.operand);3324 const ptr_ty = f.typeOf(ty_op.operand);
3325 const ptr_scalar_ty = ptr_ty.scalarType(mod);3325 const ptr_scalar_ty = ptr_ty.scalarType(mod);
3326 const ptr_info = ptr_scalar_ty.ptrInfo(mod);3326 const ptr_info = ptr_scalar_ty.ptrInfo(mod);
3327 const src_ty = ptr_info.pointee_type;3327 const src_ty = ptr_info.child.toType();
33283328
3329 if (!src_ty.hasRuntimeBitsIgnoreComptime(mod)) {3329 if (!src_ty.hasRuntimeBitsIgnoreComptime(mod)) {
3330 try reap(f, inst, &.{ty_op.operand});3330 try reap(f, inst, &.{ty_op.operand});
...@@ -3335,7 +3335,10 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3335,7 +3335,10 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
33353335
3336 try reap(f, inst, &.{ty_op.operand});3336 try reap(f, inst, &.{ty_op.operand});
33373337
3338 const is_aligned = ptr_info.@"align" == 0 or ptr_info.@"align" >= src_ty.abiAlignment(mod);3338 const is_aligned = if (ptr_info.flags.alignment.toByteUnitsOptional()) |alignment|
3339 alignment >= src_ty.abiAlignment(mod)
3340 else
3341 true;
3339 const is_array = lowersToArray(src_ty, mod);3342 const is_array = lowersToArray(src_ty, mod);
3340 const need_memcpy = !is_aligned or is_array;3343 const need_memcpy = !is_aligned or is_array;
33413344
...@@ -3354,12 +3357,12 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3354,12 +3357,12 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
3354 try writer.writeAll(", sizeof(");3357 try writer.writeAll(", sizeof(");
3355 try f.renderType(writer, src_ty);3358 try f.renderType(writer, src_ty);
3356 try writer.writeAll("))");3359 try writer.writeAll("))");
3357 } else if (ptr_info.host_size > 0 and ptr_info.vector_index == .none) {3360 } else if (ptr_info.packed_offset.host_size > 0 and ptr_info.flags.vector_index == .none) {
3358 const host_bits: u16 = ptr_info.host_size * 8;3361 const host_bits: u16 = ptr_info.packed_offset.host_size * 8;
3359 const host_ty = try mod.intType(.unsigned, host_bits);3362 const host_ty = try mod.intType(.unsigned, host_bits);
33603363
3361 const bit_offset_ty = try mod.intType(.unsigned, Type.smallestUnsignedBits(host_bits - 1));3364 const bit_offset_ty = try mod.intType(.unsigned, Type.smallestUnsignedBits(host_bits - 1));
3362 const bit_offset_val = try mod.intValue(bit_offset_ty, ptr_info.bit_offset);3365 const bit_offset_val = try mod.intValue(bit_offset_ty, ptr_info.packed_offset.bit_offset);
33633366
3364 const field_ty = try mod.intType(.unsigned, @intCast(u16, src_ty.bitSize(mod)));3367 const field_ty = try mod.intType(.unsigned, @intCast(u16, src_ty.bitSize(mod)));
33653368
...@@ -3593,20 +3596,22 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {...@@ -3593,20 +3596,22 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
35933596
3594 if (val_is_undef) {3597 if (val_is_undef) {
3595 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });3598 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
3596 if (safety and ptr_info.host_size == 0) {3599 if (safety and ptr_info.packed_offset.host_size == 0) {
3597 const writer = f.object.writer();3600 const writer = f.object.writer();
3598 try writer.writeAll("memset(");3601 try writer.writeAll("memset(");
3599 try f.writeCValue(writer, ptr_val, .FunctionArgument);3602 try f.writeCValue(writer, ptr_val, .FunctionArgument);
3600 try writer.writeAll(", 0xaa, sizeof(");3603 try writer.writeAll(", 0xaa, sizeof(");
3601 try f.renderType(writer, ptr_info.pointee_type);3604 try f.renderType(writer, ptr_info.child.toType());
3602 try writer.writeAll("));\n");3605 try writer.writeAll("));\n");
3603 }3606 }
3604 return .none;3607 return .none;
3605 }3608 }
36063609
3607 const is_aligned = ptr_info.@"align" == 0 or3610 const is_aligned = if (ptr_info.flags.alignment.toByteUnitsOptional()) |alignment|
3608 ptr_info.@"align" >= ptr_info.pointee_type.abiAlignment(mod);3611 alignment >= src_ty.abiAlignment(mod)
3609 const is_array = lowersToArray(ptr_info.pointee_type, mod);3612 else
3613 true;
3614 const is_array = lowersToArray(ptr_info.child.toType(), mod);
3610 const need_memcpy = !is_aligned or is_array;3615 const need_memcpy = !is_aligned or is_array;
36113616
3612 const src_val = try f.resolveInst(bin_op.rhs);3617 const src_val = try f.resolveInst(bin_op.rhs);
...@@ -3618,7 +3623,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {...@@ -3618,7 +3623,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
3618 if (need_memcpy) {3623 if (need_memcpy) {
3619 // For this memcpy to safely work we need the rhs to have the same3624 // For this memcpy to safely work we need the rhs to have the same
3620 // underlying type as the lhs (i.e. they must both be arrays of the same underlying type).3625 // underlying type as the lhs (i.e. they must both be arrays of the same underlying type).
3621 assert(src_ty.eql(ptr_info.pointee_type, f.object.dg.module));3626 assert(src_ty.eql(ptr_info.child.toType(), f.object.dg.module));
36223627
3623 // If the source is a constant, writeCValue will emit a brace initialization3628 // If the source is a constant, writeCValue will emit a brace initialization
3624 // so work around this by initializing into new local.3629 // so work around this by initializing into new local.
...@@ -3646,12 +3651,12 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {...@@ -3646,12 +3651,12 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
3646 if (src_val == .constant) {3651 if (src_val == .constant) {
3647 try freeLocal(f, inst, array_src.new_local, 0);3652 try freeLocal(f, inst, array_src.new_local, 0);
3648 }3653 }
3649 } else if (ptr_info.host_size > 0 and ptr_info.vector_index == .none) {3654 } else if (ptr_info.packed_offset.host_size > 0 and ptr_info.flags.vector_index == .none) {
3650 const host_bits = ptr_info.host_size * 8;3655 const host_bits = ptr_info.packed_offset.host_size * 8;
3651 const host_ty = try mod.intType(.unsigned, host_bits);3656 const host_ty = try mod.intType(.unsigned, host_bits);
36523657
3653 const bit_offset_ty = try mod.intType(.unsigned, Type.smallestUnsignedBits(host_bits - 1));3658 const bit_offset_ty = try mod.intType(.unsigned, Type.smallestUnsignedBits(host_bits - 1));
3654 const bit_offset_val = try mod.intValue(bit_offset_ty, ptr_info.bit_offset);3659 const bit_offset_val = try mod.intValue(bit_offset_ty, ptr_info.packed_offset.bit_offset);
36553660
3656 const src_bits = src_ty.bitSize(mod);3661 const src_bits = src_ty.bitSize(mod);
36573662
...@@ -3663,7 +3668,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {...@@ -3663,7 +3668,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
3663 defer mask.deinit();3668 defer mask.deinit();
36643669
3665 try mask.setTwosCompIntLimit(.max, .unsigned, @intCast(usize, src_bits));3670 try mask.setTwosCompIntLimit(.max, .unsigned, @intCast(usize, src_bits));
3666 try mask.shiftLeft(&mask, ptr_info.bit_offset);3671 try mask.shiftLeft(&mask, ptr_info.packed_offset.bit_offset);
3667 try mask.bitNotWrap(&mask, .unsigned, host_bits);3672 try mask.bitNotWrap(&mask, .unsigned, host_bits);
36683673
3669 const mask_val = try mod.intValue_big(host_ty, mask.toConst());3674 const mask_val = try mod.intValue_big(host_ty, mask.toConst());
...@@ -5201,7 +5206,7 @@ fn fieldLocation(...@@ -5201,7 +5206,7 @@ fn fieldLocation(
5201 else5206 else
5202 .{ .identifier = ip.stringToSlice(container_ty.structFieldName(next_field_index, mod)) } };5207 .{ .identifier = ip.stringToSlice(container_ty.structFieldName(next_field_index, mod)) } };
5203 } else if (container_ty.hasRuntimeBitsIgnoreComptime(mod)) .end else .begin,5208 } else if (container_ty.hasRuntimeBitsIgnoreComptime(mod)) .end else .begin,
5204 .Packed => if (field_ptr_ty.ptrInfo(mod).host_size == 0)5209 .Packed => if (field_ptr_ty.ptrInfo(mod).packed_offset.host_size == 0)
5205 .{ .byte_offset = container_ty.packedStructFieldByteOffset(field_index, mod) }5210 .{ .byte_offset = container_ty.packedStructFieldByteOffset(field_index, mod) }
5206 else5211 else
5207 .begin,5212 .begin,
src/codegen/c/type.zig+31-28
...@@ -6,6 +6,7 @@ const assert = std.debug.assert;...@@ -6,6 +6,7 @@ const assert = std.debug.assert;
6const autoHash = std.hash.autoHash;6const autoHash = std.hash.autoHash;
7const Target = std.Target;7const Target = std.Target;
88
9const Alignment = @import("../../InternPool.zig").Alignment;
9const Module = @import("../../Module.zig");10const Module = @import("../../Module.zig");
10const Type = @import("../../type.zig").Type;11const Type = @import("../../type.zig").Type;
1112
...@@ -280,16 +281,15 @@ pub const CType = extern union {...@@ -280,16 +281,15 @@ pub const CType = extern union {
280 };281 };
281282
282 pub const AlignAs = struct {283 pub const AlignAs = struct {
283 @"align": std.math.Log2Int(u32),284 @"align": Alignment,
284 abi: std.math.Log2Int(u32),285 abi: Alignment,
285286
286 pub fn init(alignment: u32, abi_alignment: u32) AlignAs {287 pub fn init(alignment: u64, abi_alignment: u32) AlignAs {
287 const actual_align = if (alignment != 0) alignment else abi_alignment;288 const @"align" = Alignment.fromByteUnits(alignment);
288 assert(std.math.isPowerOfTwo(actual_align));289 const abi_align = Alignment.fromNonzeroByteUnits(abi_alignment);
289 assert(std.math.isPowerOfTwo(abi_alignment));
290 return .{290 return .{
291 .@"align" = std.math.log2_int(u32, actual_align),291 .@"align" = if (@"align" != .none) @"align" else abi_align,
292 .abi = std.math.log2_int(u32, abi_alignment),292 .abi = abi_align,
293 };293 };
294 }294 }
295 pub fn abiAlign(ty: Type, mod: *Module) AlignAs {295 pub fn abiAlign(ty: Type, mod: *Module) AlignAs {
...@@ -308,8 +308,14 @@ pub const CType = extern union {...@@ -308,8 +308,14 @@ pub const CType = extern union {
308 return init(union_payload_align, union_payload_align);308 return init(union_payload_align, union_payload_align);
309 }309 }
310310
311 pub fn getAlign(self: AlignAs) u32 {311 pub fn order(lhs: AlignAs, rhs: AlignAs) std.math.Order {
312 return @as(u32, 1) << self.@"align";312 return lhs.@"align".order(rhs.@"align");
313 }
314 pub fn abiOrder(self: AlignAs) std.math.Order {
315 return self.@"align".order(self.abi);
316 }
317 pub fn toByteUnits(self: AlignAs) u64 {
318 return self.@"align".toByteUnitsOptional().?;
313 }319 }
314 };320 };
315321
...@@ -1298,7 +1304,7 @@ pub const CType = extern union {...@@ -1298,7 +1304,7 @@ pub const CType = extern union {
1298 const slice = self.storage.anon.fields[0..fields_len];1304 const slice = self.storage.anon.fields[0..fields_len];
1299 mem.sort(Field, slice, {}, struct {1305 mem.sort(Field, slice, {}, struct {
1300 fn before(_: void, lhs: Field, rhs: Field) bool {1306 fn before(_: void, lhs: Field, rhs: Field) bool {
1301 return lhs.alignas.@"align" > rhs.alignas.@"align";1307 return lhs.alignas.order(rhs.alignas).compare(.gt);
1302 }1308 }
1303 }.before);1309 }.before);
1304 return slice;1310 return slice;
...@@ -1424,7 +1430,7 @@ pub const CType = extern union {...@@ -1424,7 +1430,7 @@ pub const CType = extern union {
14241430
1425 .Pointer => {1431 .Pointer => {
1426 const info = ty.ptrInfo(mod);1432 const info = ty.ptrInfo(mod);
1427 switch (info.size) {1433 switch (info.flags.size) {
1428 .Slice => {1434 .Slice => {
1429 if (switch (kind) {1435 if (switch (kind) {
1430 .forward, .forward_parameter => @as(Index, undefined),1436 .forward, .forward_parameter => @as(Index, undefined),
...@@ -1454,27 +1460,24 @@ pub const CType = extern union {...@@ -1454,27 +1460,24 @@ pub const CType = extern union {
1454 },1460 },
14551461
1456 .One, .Many, .C => {1462 .One, .Many, .C => {
1457 const t: Tag = switch (info.@"volatile") {1463 const t: Tag = switch (info.flags.is_volatile) {
1458 false => switch (info.mutable) {1464 false => switch (info.flags.is_const) {
1459 true => .pointer,1465 false => .pointer,
1460 false => .pointer_const,1466 true => .pointer_const,
1461 },1467 },
1462 true => switch (info.mutable) {1468 true => switch (info.flags.is_const) {
1463 true => .pointer_volatile,1469 false => .pointer_volatile,
1464 false => .pointer_const_volatile,1470 true => .pointer_const_volatile,
1465 },1471 },
1466 };1472 };
14671473
1468 const pointee_ty = if (info.host_size > 0 and info.vector_index == .none)1474 const pointee_ty = if (info.packed_offset.host_size > 0 and
1469 try mod.intType(.unsigned, info.host_size * 8)1475 info.flags.vector_index == .none)
1476 try mod.intType(.unsigned, info.packed_offset.host_size * 8)
1470 else1477 else
1471 info.pointee_type;1478 info.child.toType();
14721479
1473 if (if (info.size == .C and pointee_ty.ip_index == .u8_type)1480 if (try lookup.typeToIndex(pointee_ty, .forward)) |child_idx| {
1474 Tag.char.toIndex()
1475 else
1476 try lookup.typeToIndex(pointee_ty, .forward)) |child_idx|
1477 {
1478 self.storage = .{ .child = .{1481 self.storage = .{ .child = .{
1479 .base = .{ .tag = t },1482 .base = .{ .tag = t },
1480 .data = child_idx,1483 .data = child_idx,
...@@ -1586,7 +1589,7 @@ pub const CType = extern union {...@@ -1586,7 +1589,7 @@ pub const CType = extern union {
1586 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;1589 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
15871590
1588 const field_align = AlignAs.fieldAlign(ty, field_i, mod);1591 const field_align = AlignAs.fieldAlign(ty, field_i, mod);
1589 if (field_align.@"align" < field_align.abi) {1592 if (field_align.abiOrder().compare(.lt)) {
1590 is_packed = true;1593 is_packed = true;
1591 if (!lookup.isMutable()) break;1594 if (!lookup.isMutable()) break;
1592 }1595 }
src/codegen/llvm.zig+74-74
...@@ -885,7 +885,7 @@ pub const Object = struct {...@@ -885,7 +885,7 @@ pub const Object = struct {
885 const llvm_func = try dg.resolveLlvmFunction(decl_index);885 const llvm_func = try dg.resolveLlvmFunction(decl_index);
886886
887 if (mod.align_stack_fns.get(func_index)) |align_info| {887 if (mod.align_stack_fns.get(func_index)) |align_info| {
888 dg.addFnAttrInt(llvm_func, "alignstack", align_info.alignment);888 dg.addFnAttrInt(llvm_func, "alignstack", align_info.alignment.toByteUnitsOptional().?);
889 dg.addFnAttr(llvm_func, "noinline");889 dg.addFnAttr(llvm_func, "noinline");
890 } else {890 } else {
891 DeclGen.removeFnAttr(llvm_func, "alignstack");891 DeclGen.removeFnAttr(llvm_func, "alignstack");
...@@ -1063,15 +1063,12 @@ pub const Object = struct {...@@ -1063,15 +1063,12 @@ pub const Object = struct {
1063 if (param_ty.zigTypeTag(mod) != .Optional) {1063 if (param_ty.zigTypeTag(mod) != .Optional) {
1064 dg.addArgAttr(llvm_func, llvm_arg_i, "nonnull");1064 dg.addArgAttr(llvm_func, llvm_arg_i, "nonnull");
1065 }1065 }
1066 if (!ptr_info.mutable) {1066 if (ptr_info.flags.is_const) {
1067 dg.addArgAttr(llvm_func, llvm_arg_i, "readonly");1067 dg.addArgAttr(llvm_func, llvm_arg_i, "readonly");
1068 }1068 }
1069 if (ptr_info.@"align" != 0) {1069 const elem_align = ptr_info.flags.alignment.toByteUnitsOptional() orelse
1070 dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", ptr_info.@"align");1070 @max(ptr_info.child.toType().abiAlignment(mod), 1);
1071 } else {1071 dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", elem_align);
1072 const elem_align = @max(ptr_info.pointee_type.abiAlignment(mod), 1);
1073 dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", elem_align);
1074 }
1075 const ptr_param = llvm_func.getParam(llvm_arg_i);1072 const ptr_param = llvm_func.getParam(llvm_arg_i);
1076 llvm_arg_i += 1;1073 llvm_arg_i += 1;
1077 const len_param = llvm_func.getParam(llvm_arg_i);1074 const len_param = llvm_func.getParam(llvm_arg_i);
...@@ -1474,7 +1471,7 @@ pub const Object = struct {...@@ -1474,7 +1471,7 @@ pub const Object = struct {
1474 .Int => {1471 .Int => {
1475 const info = ty.intInfo(mod);1472 const info = ty.intInfo(mod);
1476 assert(info.bits != 0);1473 assert(info.bits != 0);
1477 const name = try ty.nameAlloc(gpa, o.module);1474 const name = try o.allocTypeName(ty);
1478 defer gpa.free(name);1475 defer gpa.free(name);
1479 const dwarf_encoding: c_uint = switch (info.signedness) {1476 const dwarf_encoding: c_uint = switch (info.signedness) {
1480 .signed => DW.ATE.signed,1477 .signed => DW.ATE.signed,
...@@ -1536,7 +1533,7 @@ pub const Object = struct {...@@ -1536,7 +1533,7 @@ pub const Object = struct {
1536 const di_file = try o.getDIFile(gpa, mod.namespacePtr(owner_decl.src_namespace).file_scope);1533 const di_file = try o.getDIFile(gpa, mod.namespacePtr(owner_decl.src_namespace).file_scope);
1537 const di_scope = try o.namespaceToDebugScope(owner_decl.src_namespace);1534 const di_scope = try o.namespaceToDebugScope(owner_decl.src_namespace);
15381535
1539 const name = try ty.nameAlloc(gpa, o.module);1536 const name = try o.allocTypeName(ty);
1540 defer gpa.free(name);1537 defer gpa.free(name);
15411538
1542 const enum_di_ty = dib.createEnumerationType(1539 const enum_di_ty = dib.createEnumerationType(
...@@ -1557,7 +1554,7 @@ pub const Object = struct {...@@ -1557,7 +1554,7 @@ pub const Object = struct {
1557 },1554 },
1558 .Float => {1555 .Float => {
1559 const bits = ty.floatBits(target);1556 const bits = ty.floatBits(target);
1560 const name = try ty.nameAlloc(gpa, o.module);1557 const name = try o.allocTypeName(ty);
1561 defer gpa.free(name);1558 defer gpa.free(name);
1562 const di_type = dib.createBasicType(name, bits, DW.ATE.float);1559 const di_type = dib.createBasicType(name, bits, DW.ATE.float);
1563 gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_type);1560 gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_type);
...@@ -1571,7 +1568,7 @@ pub const Object = struct {...@@ -1571,7 +1568,7 @@ pub const Object = struct {
1571 },1568 },
1572 .Pointer => {1569 .Pointer => {
1573 // Normalize everything that the debug info does not represent.1570 // Normalize everything that the debug info does not represent.
1574 const ptr_info = Type.ptrInfoIp(&mod.intern_pool, ty.toIntern());1571 const ptr_info = ty.ptrInfo(mod);
15751572
1576 if (ptr_info.sentinel != .none or1573 if (ptr_info.sentinel != .none or
1577 ptr_info.flags.address_space != .generic or1574 ptr_info.flags.address_space != .generic or
...@@ -1607,7 +1604,7 @@ pub const Object = struct {...@@ -1607,7 +1604,7 @@ pub const Object = struct {
1607 const ptr_ty = ty.slicePtrFieldType(mod);1604 const ptr_ty = ty.slicePtrFieldType(mod);
1608 const len_ty = Type.usize;1605 const len_ty = Type.usize;
16091606
1610 const name = try ty.nameAlloc(gpa, o.module);1607 const name = try o.allocTypeName(ty);
1611 defer gpa.free(name);1608 defer gpa.free(name);
1612 const di_file: ?*llvm.DIFile = null;1609 const di_file: ?*llvm.DIFile = null;
1613 const line = 0;1610 const line = 0;
...@@ -1683,7 +1680,7 @@ pub const Object = struct {...@@ -1683,7 +1680,7 @@ pub const Object = struct {
1683 }1680 }
16841681
1685 const elem_di_ty = try o.lowerDebugType(ptr_info.child.toType(), .fwd);1682 const elem_di_ty = try o.lowerDebugType(ptr_info.child.toType(), .fwd);
1686 const name = try ty.nameAlloc(gpa, o.module);1683 const name = try o.allocTypeName(ty);
1687 defer gpa.free(name);1684 defer gpa.free(name);
1688 const ptr_di_ty = dib.createPointerType(1685 const ptr_di_ty = dib.createPointerType(
1689 elem_di_ty,1686 elem_di_ty,
...@@ -1701,7 +1698,7 @@ pub const Object = struct {...@@ -1701,7 +1698,7 @@ pub const Object = struct {
1701 gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_ty);1698 gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_ty);
1702 return di_ty;1699 return di_ty;
1703 }1700 }
1704 const name = try ty.nameAlloc(gpa, o.module);1701 const name = try o.allocTypeName(ty);
1705 defer gpa.free(name);1702 defer gpa.free(name);
1706 const owner_decl_index = ty.getOwnerDecl(mod);1703 const owner_decl_index = ty.getOwnerDecl(mod);
1707 const owner_decl = o.module.declPtr(owner_decl_index);1704 const owner_decl = o.module.declPtr(owner_decl_index);
...@@ -1738,7 +1735,7 @@ pub const Object = struct {...@@ -1738,7 +1735,7 @@ pub const Object = struct {
1738 .Int => blk: {1735 .Int => blk: {
1739 const info = elem_ty.intInfo(mod);1736 const info = elem_ty.intInfo(mod);
1740 assert(info.bits != 0);1737 assert(info.bits != 0);
1741 const name = try ty.nameAlloc(gpa, o.module);1738 const name = try o.allocTypeName(ty);
1742 defer gpa.free(name);1739 defer gpa.free(name);
1743 const dwarf_encoding: c_uint = switch (info.signedness) {1740 const dwarf_encoding: c_uint = switch (info.signedness) {
1744 .signed => DW.ATE.signed,1741 .signed => DW.ATE.signed,
...@@ -1761,7 +1758,7 @@ pub const Object = struct {...@@ -1761,7 +1758,7 @@ pub const Object = struct {
1761 return vector_di_ty;1758 return vector_di_ty;
1762 },1759 },
1763 .Optional => {1760 .Optional => {
1764 const name = try ty.nameAlloc(gpa, o.module);1761 const name = try o.allocTypeName(ty);
1765 defer gpa.free(name);1762 defer gpa.free(name);
1766 const child_ty = ty.optionalChild(mod);1763 const child_ty = ty.optionalChild(mod);
1767 if (!child_ty.hasRuntimeBitsIgnoreComptime(mod)) {1764 if (!child_ty.hasRuntimeBitsIgnoreComptime(mod)) {
...@@ -1857,7 +1854,7 @@ pub const Object = struct {...@@ -1857,7 +1854,7 @@ pub const Object = struct {
1857 try o.di_type_map.put(gpa, ty.toIntern(), AnnotatedDITypePtr.initFull(err_set_di_ty));1854 try o.di_type_map.put(gpa, ty.toIntern(), AnnotatedDITypePtr.initFull(err_set_di_ty));
1858 return err_set_di_ty;1855 return err_set_di_ty;
1859 }1856 }
1860 const name = try ty.nameAlloc(gpa, o.module);1857 const name = try o.allocTypeName(ty);
1861 defer gpa.free(name);1858 defer gpa.free(name);
1862 const di_file: ?*llvm.DIFile = null;1859 const di_file: ?*llvm.DIFile = null;
1863 const line = 0;1860 const line = 0;
...@@ -1949,7 +1946,7 @@ pub const Object = struct {...@@ -1949,7 +1946,7 @@ pub const Object = struct {
1949 },1946 },
1950 .Struct => {1947 .Struct => {
1951 const compile_unit_scope = o.di_compile_unit.?.toScope();1948 const compile_unit_scope = o.di_compile_unit.?.toScope();
1952 const name = try ty.nameAlloc(gpa, o.module);1949 const name = try o.allocTypeName(ty);
1953 defer gpa.free(name);1950 defer gpa.free(name);
19541951
1955 if (mod.typeToStruct(ty)) |struct_obj| {1952 if (mod.typeToStruct(ty)) |struct_obj| {
...@@ -2128,7 +2125,7 @@ pub const Object = struct {...@@ -2128,7 +2125,7 @@ pub const Object = struct {
2128 const compile_unit_scope = o.di_compile_unit.?.toScope();2125 const compile_unit_scope = o.di_compile_unit.?.toScope();
2129 const owner_decl_index = ty.getOwnerDecl(mod);2126 const owner_decl_index = ty.getOwnerDecl(mod);
21302127
2131 const name = try ty.nameAlloc(gpa, o.module);2128 const name = try o.allocTypeName(ty);
2132 defer gpa.free(name);2129 defer gpa.free(name);
21332130
2134 const fwd_decl = opt_fwd_decl orelse blk: {2131 const fwd_decl = opt_fwd_decl orelse blk: {
...@@ -2417,6 +2414,13 @@ pub const Object = struct {...@@ -2417,6 +2414,13 @@ pub const Object = struct {
2417 assert(stack_trace_decl.has_tv);2414 assert(stack_trace_decl.has_tv);
2418 return stack_trace_decl.val.toType();2415 return stack_trace_decl.val.toType();
2419 }2416 }
2417
2418 fn allocTypeName(o: *Object, ty: Type) Allocator.Error![:0]const u8 {
2419 var buffer = std.ArrayList(u8).init(o.gpa);
2420 errdefer buffer.deinit();
2421 try ty.print(buffer.writer(), o.module);
2422 return buffer.toOwnedSliceSentinel(0);
2423 }
2420};2424};
24212425
2422pub const DeclGen = struct {2426pub const DeclGen = struct {
...@@ -2792,7 +2796,7 @@ pub const DeclGen = struct {...@@ -2792,7 +2796,7 @@ pub const DeclGen = struct {
2792 return dg.context.structType(&fields, fields.len, .False);2796 return dg.context.structType(&fields, fields.len, .False);
2793 }2797 }
2794 const ptr_info = t.ptrInfo(mod);2798 const ptr_info = t.ptrInfo(mod);
2795 const llvm_addrspace = toLlvmAddressSpace(ptr_info.@"addrspace", target);2799 const llvm_addrspace = toLlvmAddressSpace(ptr_info.flags.address_space, target);
2796 return dg.context.pointerType(llvm_addrspace);2800 return dg.context.pointerType(llvm_addrspace);
2797 },2801 },
2798 .Opaque => {2802 .Opaque => {
...@@ -3392,7 +3396,7 @@ pub const DeclGen = struct {...@@ -3392,7 +3396,7 @@ pub const DeclGen = struct {
3392 .opt_payload,3396 .opt_payload,
3393 .elem,3397 .elem,
3394 .field,3398 .field,
3395 => try dg.lowerParentPtr(ptr_tv.val, ptr_tv.ty.ptrInfo(mod).bit_offset % 8 == 0),3399 => try dg.lowerParentPtr(ptr_tv.val, ptr_tv.ty.ptrInfo(mod).packed_offset.bit_offset % 8 == 0),
3396 .comptime_field => unreachable,3400 .comptime_field => unreachable,
3397 };3401 };
3398 switch (ptr.len) {3402 switch (ptr.len) {
...@@ -4034,7 +4038,6 @@ pub const DeclGen = struct {...@@ -4034,7 +4038,6 @@ pub const DeclGen = struct {
40344038
4035 fn lowerPtrToVoid(dg: *DeclGen, ptr_ty: Type) !*llvm.Value {4039 fn lowerPtrToVoid(dg: *DeclGen, ptr_ty: Type) !*llvm.Value {
4036 const mod = dg.module;4040 const mod = dg.module;
4037 const alignment = ptr_ty.ptrInfo(mod).@"align";
4038 // Even though we are pointing at something which has zero bits (e.g. `void`),4041 // Even though we are pointing at something which has zero bits (e.g. `void`),
4039 // Pointers are defined to have bits. So we must return something here.4042 // Pointers are defined to have bits. So we must return something here.
4040 // The value cannot be undefined, because we use the `nonnull` annotation4043 // The value cannot be undefined, because we use the `nonnull` annotation
...@@ -4042,7 +4045,7 @@ pub const DeclGen = struct {...@@ -4042,7 +4045,7 @@ pub const DeclGen = struct {
4042 // the address will never be dereferenced.4045 // the address will never be dereferenced.
4043 const llvm_usize = try dg.lowerType(Type.usize);4046 const llvm_usize = try dg.lowerType(Type.usize);
4044 const llvm_ptr_ty = try dg.lowerType(ptr_ty);4047 const llvm_ptr_ty = try dg.lowerType(ptr_ty);
4045 if (alignment != 0) {4048 if (ptr_ty.ptrInfo(mod).flags.alignment.toByteUnitsOptional()) |alignment| {
4046 return llvm_usize.constInt(alignment, .False).constIntToPtr(llvm_ptr_ty);4049 return llvm_usize.constInt(alignment, .False).constIntToPtr(llvm_ptr_ty);
4047 }4050 }
4048 // Note that these 0xaa values are appropriate even in release-optimized builds4051 // Note that these 0xaa values are appropriate even in release-optimized builds
...@@ -4163,18 +4166,15 @@ pub const DeclGen = struct {...@@ -4163,18 +4166,15 @@ pub const DeclGen = struct {
4163 dg.addArgAttr(llvm_fn, llvm_arg_i, "noalias");4166 dg.addArgAttr(llvm_fn, llvm_arg_i, "noalias");
4164 }4167 }
4165 }4168 }
4166 if (!param_ty.isPtrLikeOptional(mod) and !ptr_info.@"allowzero") {4169 if (!param_ty.isPtrLikeOptional(mod) and !ptr_info.flags.is_allowzero) {
4167 dg.addArgAttr(llvm_fn, llvm_arg_i, "nonnull");4170 dg.addArgAttr(llvm_fn, llvm_arg_i, "nonnull");
4168 }4171 }
4169 if (!ptr_info.mutable) {4172 if (ptr_info.flags.is_const) {
4170 dg.addArgAttr(llvm_fn, llvm_arg_i, "readonly");4173 dg.addArgAttr(llvm_fn, llvm_arg_i, "readonly");
4171 }4174 }
4172 if (ptr_info.@"align" != 0) {4175 const elem_align = ptr_info.flags.alignment.toByteUnitsOptional() orelse
4173 dg.addArgAttrInt(llvm_fn, llvm_arg_i, "align", ptr_info.@"align");4176 @max(ptr_info.child.toType().abiAlignment(mod), 1);
4174 } else {4177 dg.addArgAttrInt(llvm_fn, llvm_arg_i, "align", elem_align);
4175 const elem_align = @max(ptr_info.pointee_type.abiAlignment(mod), 1);
4176 dg.addArgAttrInt(llvm_fn, llvm_arg_i, "align", elem_align);
4177 }
4178 } else if (ccAbiPromoteInt(fn_info.cc, mod, param_ty)) |s| switch (s) {4178 } else if (ccAbiPromoteInt(fn_info.cc, mod, param_ty)) |s| switch (s) {
4179 .signed => dg.addArgAttr(llvm_fn, llvm_arg_i, "signext"),4179 .signed => dg.addArgAttr(llvm_fn, llvm_arg_i, "signext"),
4180 .unsigned => dg.addArgAttr(llvm_fn, llvm_arg_i, "zeroext"),4180 .unsigned => dg.addArgAttr(llvm_fn, llvm_arg_i, "zeroext"),
...@@ -4806,15 +4806,12 @@ pub const FuncGen = struct {...@@ -4806,15 +4806,12 @@ pub const FuncGen = struct {
4806 if (param_ty.zigTypeTag(mod) != .Optional) {4806 if (param_ty.zigTypeTag(mod) != .Optional) {
4807 self.dg.addArgAttr(call, llvm_arg_i, "nonnull");4807 self.dg.addArgAttr(call, llvm_arg_i, "nonnull");
4808 }4808 }
4809 if (!ptr_info.mutable) {4809 if (ptr_info.flags.is_const) {
4810 self.dg.addArgAttr(call, llvm_arg_i, "readonly");4810 self.dg.addArgAttr(call, llvm_arg_i, "readonly");
4811 }4811 }
4812 if (ptr_info.@"align" != 0) {4812 const elem_align = ptr_info.flags.alignment.toByteUnitsOptional() orelse
4813 self.dg.addArgAttrInt(call, llvm_arg_i, "align", ptr_info.@"align");4813 @max(ptr_info.child.toType().abiAlignment(mod), 1);
4814 } else {4814 self.dg.addArgAttrInt(call, llvm_arg_i, "align", elem_align);
4815 const elem_align = @max(ptr_info.pointee_type.abiAlignment(mod), 1);
4816 self.dg.addArgAttrInt(call, llvm_arg_i, "align", elem_align);
4817 }
4818 },4815 },
4819 };4816 };
4820 }4817 }
...@@ -5737,7 +5734,7 @@ pub const FuncGen = struct {...@@ -5737,7 +5734,7 @@ pub const FuncGen = struct {
5737 const rhs = try self.resolveInst(bin_op.rhs);5734 const rhs = try self.resolveInst(bin_op.rhs);
57385735
5739 const elem_ptr = self.air.getRefType(ty_pl.ty);5736 const elem_ptr = self.air.getRefType(ty_pl.ty);
5740 if (elem_ptr.ptrInfo(mod).vector_index != .none) return base_ptr;5737 if (elem_ptr.ptrInfo(mod).flags.vector_index != .none) return base_ptr;
57415738
5742 const llvm_elem_ty = try self.dg.lowerPtrElemTy(elem_ty);5739 const llvm_elem_ty = try self.dg.lowerPtrElemTy(elem_ty);
5743 if (ptr_ty.isSinglePointer(mod)) {5740 if (ptr_ty.isSinglePointer(mod)) {
...@@ -8062,7 +8059,7 @@ pub const FuncGen = struct {...@@ -8062,7 +8059,7 @@ pub const FuncGen = struct {
8062 const ptr = try fg.resolveInst(ty_op.operand);8059 const ptr = try fg.resolveInst(ty_op.operand);
80638060
8064 elide: {8061 elide: {
8065 if (!isByRef(ptr_info.pointee_type, mod)) break :elide;8062 if (!isByRef(ptr_info.child.toType(), mod)) break :elide;
8066 if (!canElideLoad(fg, body_tail)) break :elide;8063 if (!canElideLoad(fg, body_tail)) break :elide;
8067 return ptr;8064 return ptr;
8068 }8065 }
...@@ -8235,13 +8232,14 @@ pub const FuncGen = struct {...@@ -8235,13 +8232,14 @@ pub const FuncGen = struct {
8235 const ptr = try self.resolveInst(atomic_load.ptr);8232 const ptr = try self.resolveInst(atomic_load.ptr);
8236 const ptr_ty = self.typeOf(atomic_load.ptr);8233 const ptr_ty = self.typeOf(atomic_load.ptr);
8237 const ptr_info = ptr_ty.ptrInfo(mod);8234 const ptr_info = ptr_ty.ptrInfo(mod);
8238 const elem_ty = ptr_info.pointee_type;8235 const elem_ty = ptr_info.child.toType();
8239 if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod))8236 if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod))
8240 return null;8237 return null;
8241 const ordering = toLlvmAtomicOrdering(atomic_load.order);8238 const ordering = toLlvmAtomicOrdering(atomic_load.order);
8242 const opt_abi_llvm_ty = self.dg.getAtomicAbiType(elem_ty, false);8239 const opt_abi_llvm_ty = self.dg.getAtomicAbiType(elem_ty, false);
8243 const ptr_alignment = ptr_info.alignment(mod);8240 const ptr_alignment = @intCast(u32, ptr_info.flags.alignment.toByteUnitsOptional() orelse
8244 const ptr_volatile = llvm.Bool.fromBool(ptr_info.@"volatile");8241 ptr_info.child.toType().abiAlignment(mod));
8242 const ptr_volatile = llvm.Bool.fromBool(ptr_info.flags.is_volatile);
8245 const elem_llvm_ty = try self.dg.lowerType(elem_ty);8243 const elem_llvm_ty = try self.dg.lowerType(elem_ty);
82468244
8247 if (opt_abi_llvm_ty) |abi_llvm_ty| {8245 if (opt_abi_llvm_ty) |abi_llvm_ty| {
...@@ -9567,7 +9565,7 @@ pub const FuncGen = struct {...@@ -9567,7 +9565,7 @@ pub const FuncGen = struct {
9567 const result_ty = self.typeOfIndex(inst);9565 const result_ty = self.typeOfIndex(inst);
9568 const result_ty_info = result_ty.ptrInfo(mod);9566 const result_ty_info = result_ty.ptrInfo(mod);
95699567
9570 if (result_ty_info.host_size != 0) {9568 if (result_ty_info.packed_offset.host_size != 0) {
9571 // From LLVM's perspective, a pointer to a packed struct and a pointer9569 // From LLVM's perspective, a pointer to a packed struct and a pointer
9572 // to a field of a packed struct are the same. The difference is in the9570 // to a field of a packed struct are the same. The difference is in the
9573 // Zig pointer type which provides information for how to mask and shift9571 // Zig pointer type which provides information for how to mask and shift
...@@ -9651,16 +9649,18 @@ pub const FuncGen = struct {...@@ -9651,16 +9649,18 @@ pub const FuncGen = struct {
9651 fn load(self: *FuncGen, ptr: *llvm.Value, ptr_ty: Type) !?*llvm.Value {9649 fn load(self: *FuncGen, ptr: *llvm.Value, ptr_ty: Type) !?*llvm.Value {
9652 const mod = self.dg.module;9650 const mod = self.dg.module;
9653 const info = ptr_ty.ptrInfo(mod);9651 const info = ptr_ty.ptrInfo(mod);
9654 if (!info.pointee_type.hasRuntimeBitsIgnoreComptime(mod)) return null;9652 const elem_ty = info.child.toType();
9653 if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod)) return null;
96559654
9656 const ptr_alignment = info.alignment(mod);9655 const ptr_alignment = @intCast(u32, info.flags.alignment.toByteUnitsOptional() orelse
9657 const ptr_volatile = llvm.Bool.fromBool(ptr_ty.isVolatilePtr(mod));9656 elem_ty.abiAlignment(mod));
9657 const ptr_volatile = llvm.Bool.fromBool(info.flags.is_volatile);
96589658
9659 assert(info.vector_index != .runtime);9659 assert(info.flags.vector_index != .runtime);
9660 if (info.vector_index != .none) {9660 if (info.flags.vector_index != .none) {
9661 const index_u32 = self.context.intType(32).constInt(@intFromEnum(info.vector_index), .False);9661 const index_u32 = self.context.intType(32).constInt(@intFromEnum(info.flags.vector_index), .False);
9662 const vec_elem_ty = try self.dg.lowerType(info.pointee_type);9662 const vec_elem_ty = try self.dg.lowerType(elem_ty);
9663 const vec_ty = vec_elem_ty.vectorType(info.host_size);9663 const vec_ty = vec_elem_ty.vectorType(info.packed_offset.host_size);
96649664
9665 const loaded_vector = self.builder.buildLoad(vec_ty, ptr, "");9665 const loaded_vector = self.builder.buildLoad(vec_ty, ptr, "");
9666 loaded_vector.setAlignment(ptr_alignment);9666 loaded_vector.setAlignment(ptr_alignment);
...@@ -9669,29 +9669,29 @@ pub const FuncGen = struct {...@@ -9669,29 +9669,29 @@ pub const FuncGen = struct {
9669 return self.builder.buildExtractElement(loaded_vector, index_u32, "");9669 return self.builder.buildExtractElement(loaded_vector, index_u32, "");
9670 }9670 }
96719671
9672 if (info.host_size == 0) {9672 if (info.packed_offset.host_size == 0) {
9673 if (isByRef(info.pointee_type, mod)) {9673 if (isByRef(elem_ty, mod)) {
9674 return self.loadByRef(ptr, info.pointee_type, ptr_alignment, info.@"volatile");9674 return self.loadByRef(ptr, elem_ty, ptr_alignment, info.flags.is_volatile);
9675 }9675 }
9676 const elem_llvm_ty = try self.dg.lowerType(info.pointee_type);9676 const elem_llvm_ty = try self.dg.lowerType(elem_ty);
9677 const llvm_inst = self.builder.buildLoad(elem_llvm_ty, ptr, "");9677 const llvm_inst = self.builder.buildLoad(elem_llvm_ty, ptr, "");
9678 llvm_inst.setAlignment(ptr_alignment);9678 llvm_inst.setAlignment(ptr_alignment);
9679 llvm_inst.setVolatile(ptr_volatile);9679 llvm_inst.setVolatile(ptr_volatile);
9680 return llvm_inst;9680 return llvm_inst;
9681 }9681 }
96829682
9683 const int_elem_ty = self.context.intType(info.host_size * 8);9683 const int_elem_ty = self.context.intType(info.packed_offset.host_size * 8);
9684 const containing_int = self.builder.buildLoad(int_elem_ty, ptr, "");9684 const containing_int = self.builder.buildLoad(int_elem_ty, ptr, "");
9685 containing_int.setAlignment(ptr_alignment);9685 containing_int.setAlignment(ptr_alignment);
9686 containing_int.setVolatile(ptr_volatile);9686 containing_int.setVolatile(ptr_volatile);
96879687
9688 const elem_bits = @intCast(c_uint, ptr_ty.childType(mod).bitSize(mod));9688 const elem_bits = @intCast(c_uint, ptr_ty.childType(mod).bitSize(mod));
9689 const shift_amt = containing_int.typeOf().constInt(info.bit_offset, .False);9689 const shift_amt = containing_int.typeOf().constInt(info.packed_offset.bit_offset, .False);
9690 const shifted_value = self.builder.buildLShr(containing_int, shift_amt, "");9690 const shifted_value = self.builder.buildLShr(containing_int, shift_amt, "");
9691 const elem_llvm_ty = try self.dg.lowerType(info.pointee_type);9691 const elem_llvm_ty = try self.dg.lowerType(elem_ty);
96929692
9693 if (isByRef(info.pointee_type, mod)) {9693 if (isByRef(elem_ty, mod)) {
9694 const result_align = info.pointee_type.abiAlignment(mod);9694 const result_align = elem_ty.abiAlignment(mod);
9695 const result_ptr = self.buildAlloca(elem_llvm_ty, result_align);9695 const result_ptr = self.buildAlloca(elem_llvm_ty, result_align);
96969696
9697 const same_size_int = self.context.intType(elem_bits);9697 const same_size_int = self.context.intType(elem_bits);
...@@ -9701,13 +9701,13 @@ pub const FuncGen = struct {...@@ -9701,13 +9701,13 @@ pub const FuncGen = struct {
9701 return result_ptr;9701 return result_ptr;
9702 }9702 }
97039703
9704 if (info.pointee_type.zigTypeTag(mod) == .Float or info.pointee_type.zigTypeTag(mod) == .Vector) {9704 if (elem_ty.zigTypeTag(mod) == .Float or elem_ty.zigTypeTag(mod) == .Vector) {
9705 const same_size_int = self.context.intType(elem_bits);9705 const same_size_int = self.context.intType(elem_bits);
9706 const truncated_int = self.builder.buildTrunc(shifted_value, same_size_int, "");9706 const truncated_int = self.builder.buildTrunc(shifted_value, same_size_int, "");
9707 return self.builder.buildBitCast(truncated_int, elem_llvm_ty, "");9707 return self.builder.buildBitCast(truncated_int, elem_llvm_ty, "");
9708 }9708 }
97099709
9710 if (info.pointee_type.isPtrAtRuntime(mod)) {9710 if (elem_ty.isPtrAtRuntime(mod)) {
9711 const same_size_int = self.context.intType(elem_bits);9711 const same_size_int = self.context.intType(elem_bits);
9712 const truncated_int = self.builder.buildTrunc(shifted_value, same_size_int, "");9712 const truncated_int = self.builder.buildTrunc(shifted_value, same_size_int, "");
9713 return self.builder.buildIntToPtr(truncated_int, elem_llvm_ty, "");9713 return self.builder.buildIntToPtr(truncated_int, elem_llvm_ty, "");
...@@ -9725,18 +9725,18 @@ pub const FuncGen = struct {...@@ -9725,18 +9725,18 @@ pub const FuncGen = struct {
9725 ) !void {9725 ) !void {
9726 const mod = self.dg.module;9726 const mod = self.dg.module;
9727 const info = ptr_ty.ptrInfo(mod);9727 const info = ptr_ty.ptrInfo(mod);
9728 const elem_ty = info.pointee_type;9728 const elem_ty = info.child.toType();
9729 if (!elem_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) {9729 if (!elem_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) {
9730 return;9730 return;
9731 }9731 }
9732 const ptr_alignment = ptr_ty.ptrAlignment(mod);9732 const ptr_alignment = ptr_ty.ptrAlignment(mod);
9733 const ptr_volatile = llvm.Bool.fromBool(info.@"volatile");9733 const ptr_volatile = llvm.Bool.fromBool(info.flags.is_volatile);
97349734
9735 assert(info.vector_index != .runtime);9735 assert(info.flags.vector_index != .runtime);
9736 if (info.vector_index != .none) {9736 if (info.flags.vector_index != .none) {
9737 const index_u32 = self.context.intType(32).constInt(@intFromEnum(info.vector_index), .False);9737 const index_u32 = self.context.intType(32).constInt(@intFromEnum(info.flags.vector_index), .False);
9738 const vec_elem_ty = try self.dg.lowerType(elem_ty);9738 const vec_elem_ty = try self.dg.lowerType(elem_ty);
9739 const vec_ty = vec_elem_ty.vectorType(info.host_size);9739 const vec_ty = vec_elem_ty.vectorType(info.packed_offset.host_size);
97409740
9741 const loaded_vector = self.builder.buildLoad(vec_ty, ptr, "");9741 const loaded_vector = self.builder.buildLoad(vec_ty, ptr, "");
9742 loaded_vector.setAlignment(ptr_alignment);9742 loaded_vector.setAlignment(ptr_alignment);
...@@ -9751,15 +9751,15 @@ pub const FuncGen = struct {...@@ -9751,15 +9751,15 @@ pub const FuncGen = struct {
9751 return;9751 return;
9752 }9752 }
97539753
9754 if (info.host_size != 0) {9754 if (info.packed_offset.host_size != 0) {
9755 const int_elem_ty = self.context.intType(info.host_size * 8);9755 const int_elem_ty = self.context.intType(info.packed_offset.host_size * 8);
9756 const containing_int = self.builder.buildLoad(int_elem_ty, ptr, "");9756 const containing_int = self.builder.buildLoad(int_elem_ty, ptr, "");
9757 assert(ordering == .NotAtomic);9757 assert(ordering == .NotAtomic);
9758 containing_int.setAlignment(ptr_alignment);9758 containing_int.setAlignment(ptr_alignment);
9759 containing_int.setVolatile(ptr_volatile);9759 containing_int.setVolatile(ptr_volatile);
9760 const elem_bits = @intCast(c_uint, ptr_ty.childType(mod).bitSize(mod));9760 const elem_bits = @intCast(c_uint, ptr_ty.childType(mod).bitSize(mod));
9761 const containing_int_ty = containing_int.typeOf();9761 const containing_int_ty = containing_int.typeOf();
9762 const shift_amt = containing_int_ty.constInt(info.bit_offset, .False);9762 const shift_amt = containing_int_ty.constInt(info.packed_offset.bit_offset, .False);
9763 // Convert to equally-sized integer type in order to perform the bit9763 // Convert to equally-sized integer type in order to perform the bit
9764 // operations on the value to store9764 // operations on the value to store
9765 const value_bits_type = self.context.intType(elem_bits);9765 const value_bits_type = self.context.intType(elem_bits);
...@@ -9799,7 +9799,7 @@ pub const FuncGen = struct {...@@ -9799,7 +9799,7 @@ pub const FuncGen = struct {
9799 elem,9799 elem,
9800 elem_ty.abiAlignment(mod),9800 elem_ty.abiAlignment(mod),
9801 self.context.intType(Type.usize.intInfo(mod).bits).constInt(size_bytes, .False),9801 self.context.intType(Type.usize.intInfo(mod).bits).constInt(size_bytes, .False),
9802 info.@"volatile",9802 info.flags.is_volatile,
9803 );9803 );
9804 }9804 }
98059805
src/codegen/spirv.zig+4-4
...@@ -1210,13 +1210,13 @@ pub const DeclGen = struct {...@@ -1210,13 +1210,13 @@ pub const DeclGen = struct {
1210 .Pointer => {1210 .Pointer => {
1211 const ptr_info = ty.ptrInfo(mod);1211 const ptr_info = ty.ptrInfo(mod);
12121212
1213 const storage_class = spvStorageClass(ptr_info.@"addrspace");1213 const storage_class = spvStorageClass(ptr_info.flags.address_space);
1214 const child_ty_ref = try self.resolveType(ptr_info.pointee_type, .indirect);1214 const child_ty_ref = try self.resolveType(ptr_info.child.toType(), .indirect);
1215 const ptr_ty_ref = try self.spv.resolve(.{ .ptr_type = .{1215 const ptr_ty_ref = try self.spv.resolve(.{ .ptr_type = .{
1216 .storage_class = storage_class,1216 .storage_class = storage_class,
1217 .child_type = child_ty_ref,1217 .child_type = child_ty_ref,
1218 } });1218 } });
1219 if (ptr_info.size != .Slice) {1219 if (ptr_info.flags.size != .Slice) {
1220 return ptr_ty_ref;1220 return ptr_ty_ref;
1221 }1221 }
12221222
...@@ -1573,7 +1573,7 @@ pub const DeclGen = struct {...@@ -1573,7 +1573,7 @@ pub const DeclGen = struct {
1573 init_val,1573 init_val,
1574 actual_storage_class,1574 actual_storage_class,
1575 final_storage_class == .Generic,1575 final_storage_class == .Generic,
1576 decl.@"align",1576 @intCast(u32, decl.alignment.toByteUnits(0)),
1577 );1577 );
1578 }1578 }
1579 }1579 }
src/link/Dwarf.zig+15-31
...@@ -163,7 +163,6 @@ pub const DeclState = struct {...@@ -163,7 +163,6 @@ pub const DeclState = struct {
163 atom_index: Atom.Index,163 atom_index: Atom.Index,
164 ty: Type,164 ty: Type,
165 ) error{OutOfMemory}!void {165 ) error{OutOfMemory}!void {
166 const arena = self.abbrev_type_arena.allocator();
167 const dbg_info_buffer = &self.dbg_info;166 const dbg_info_buffer = &self.dbg_info;
168 const target = mod.getTarget();167 const target = mod.getTarget();
169 const target_endian = target.cpu.arch.endian();168 const target_endian = target.cpu.arch.endian();
...@@ -344,10 +343,8 @@ pub const DeclState = struct {...@@ -344,10 +343,8 @@ pub const DeclState = struct {
344 .struct_type => |struct_type| s: {343 .struct_type => |struct_type| s: {
345 const struct_obj = mod.structPtrUnwrap(struct_type.index) orelse break :s;344 const struct_obj = mod.structPtrUnwrap(struct_type.index) orelse break :s;
346 // DW.AT.name, DW.FORM.string345 // DW.AT.name, DW.FORM.string
347 const struct_name = try ty.nameAllocArena(arena, mod);346 try ty.print(dbg_info_buffer.writer(), mod);
348 try dbg_info_buffer.ensureUnusedCapacity(struct_name.len + 1);347 try dbg_info_buffer.append(0);
349 dbg_info_buffer.appendSliceAssumeCapacity(struct_name);
350 dbg_info_buffer.appendAssumeCapacity(0);
351348
352 if (struct_obj.layout == .Packed) {349 if (struct_obj.layout == .Packed) {
353 log.debug("TODO implement .debug_info for packed structs", .{});350 log.debug("TODO implement .debug_info for packed structs", .{});
...@@ -388,10 +385,8 @@ pub const DeclState = struct {...@@ -388,10 +385,8 @@ pub const DeclState = struct {
388 // DW.AT.byte_size, DW.FORM.udata385 // DW.AT.byte_size, DW.FORM.udata
389 try leb128.writeULEB128(dbg_info_buffer.writer(), ty.abiSize(mod));386 try leb128.writeULEB128(dbg_info_buffer.writer(), ty.abiSize(mod));
390 // DW.AT.name, DW.FORM.string387 // DW.AT.name, DW.FORM.string
391 const enum_name = try ty.nameAllocArena(arena, mod);388 try ty.print(dbg_info_buffer.writer(), mod);
392 try dbg_info_buffer.ensureUnusedCapacity(enum_name.len + 1);389 try dbg_info_buffer.append(0);
393 dbg_info_buffer.appendSliceAssumeCapacity(enum_name);
394 dbg_info_buffer.appendAssumeCapacity(0);
395390
396 const enum_type = mod.intern_pool.indexToKey(ty.ip_index).enum_type;391 const enum_type = mod.intern_pool.indexToKey(ty.ip_index).enum_type;
397 for (enum_type.names, 0..) |field_name_index, field_i| {392 for (enum_type.names, 0..) |field_name_index, field_i| {
...@@ -422,21 +417,18 @@ pub const DeclState = struct {...@@ -422,21 +417,18 @@ pub const DeclState = struct {
422 const union_obj = mod.typeToUnion(ty).?;417 const union_obj = mod.typeToUnion(ty).?;
423 const payload_offset = if (layout.tag_align >= layout.payload_align) layout.tag_size else 0;418 const payload_offset = if (layout.tag_align >= layout.payload_align) layout.tag_size else 0;
424 const tag_offset = if (layout.tag_align >= layout.payload_align) 0 else layout.payload_size;419 const tag_offset = if (layout.tag_align >= layout.payload_align) 0 else layout.payload_size;
425 const is_tagged = layout.tag_size > 0;
426 const union_name = try ty.nameAllocArena(arena, mod);
427
428 // TODO this is temporary to match current state of unions in Zig - we don't yet have420 // TODO this is temporary to match current state of unions in Zig - we don't yet have
429 // safety checks implemented meaning the implicit tag is not yet stored and generated421 // safety checks implemented meaning the implicit tag is not yet stored and generated
430 // for untagged unions.422 // for untagged unions.
423 const is_tagged = layout.tag_size > 0;
431 if (is_tagged) {424 if (is_tagged) {
432 // DW.AT.structure_type425 // DW.AT.structure_type
433 try dbg_info_buffer.append(@intFromEnum(AbbrevKind.struct_type));426 try dbg_info_buffer.append(@intFromEnum(AbbrevKind.struct_type));
434 // DW.AT.byte_size, DW.FORM.udata427 // DW.AT.byte_size, DW.FORM.udata
435 try leb128.writeULEB128(dbg_info_buffer.writer(), layout.abi_size);428 try leb128.writeULEB128(dbg_info_buffer.writer(), layout.abi_size);
436 // DW.AT.name, DW.FORM.string429 // DW.AT.name, DW.FORM.string
437 try dbg_info_buffer.ensureUnusedCapacity(union_name.len + 1);430 try ty.print(dbg_info_buffer.writer(), mod);
438 dbg_info_buffer.appendSliceAssumeCapacity(union_name);431 try dbg_info_buffer.append(0);
439 dbg_info_buffer.appendAssumeCapacity(0);
440432
441 // DW.AT.member433 // DW.AT.member
442 try dbg_info_buffer.ensureUnusedCapacity(9);434 try dbg_info_buffer.ensureUnusedCapacity(9);
...@@ -460,7 +452,8 @@ pub const DeclState = struct {...@@ -460,7 +452,8 @@ pub const DeclState = struct {
460 if (is_tagged) {452 if (is_tagged) {
461 try dbg_info_buffer.writer().print("AnonUnion\x00", .{});453 try dbg_info_buffer.writer().print("AnonUnion\x00", .{});
462 } else {454 } else {
463 try dbg_info_buffer.writer().print("{s}\x00", .{union_name});455 try ty.print(dbg_info_buffer.writer(), mod);
456 try dbg_info_buffer.append(0);
464 }457 }
465458
466 const fields = ty.unionFields(mod);459 const fields = ty.unionFields(mod);
...@@ -500,15 +493,7 @@ pub const DeclState = struct {...@@ -500,15 +493,7 @@ pub const DeclState = struct {
500 try dbg_info_buffer.append(0);493 try dbg_info_buffer.append(0);
501 }494 }
502 },495 },
503 .ErrorSet => {496 .ErrorSet => try addDbgInfoErrorSet(mod, ty, target, &self.dbg_info),
504 try addDbgInfoErrorSet(
505 self.abbrev_type_arena.allocator(),
506 mod,
507 ty,
508 target,
509 &self.dbg_info,
510 );
511 },
512 .ErrorUnion => {497 .ErrorUnion => {
513 const error_ty = ty.errorUnionSet(mod);498 const error_ty = ty.errorUnionSet(mod);
514 const payload_ty = ty.errorUnionPayload(mod);499 const payload_ty = ty.errorUnionPayload(mod);
...@@ -523,8 +508,8 @@ pub const DeclState = struct {...@@ -523,8 +508,8 @@ pub const DeclState = struct {
523 // DW.AT.byte_size, DW.FORM.udata508 // DW.AT.byte_size, DW.FORM.udata
524 try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size);509 try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size);
525 // DW.AT.name, DW.FORM.string510 // DW.AT.name, DW.FORM.string
526 const name = try ty.nameAllocArena(arena, mod);511 try ty.print(dbg_info_buffer.writer(), mod);
527 try dbg_info_buffer.writer().print("{s}\x00", .{name});512 try dbg_info_buffer.append(0);
528513
529 if (!payload_ty.isNoReturn(mod)) {514 if (!payload_ty.isNoReturn(mod)) {
530 // DW.AT.member515 // DW.AT.member
...@@ -2527,7 +2512,7 @@ pub fn flushModule(self: *Dwarf, module: *Module) !void {...@@ -2527,7 +2512,7 @@ pub fn flushModule(self: *Dwarf, module: *Module) !void {
25272512
2528 const error_ty = try module.intern(.{ .error_set_type = .{ .names = names } });2513 const error_ty = try module.intern(.{ .error_set_type = .{ .names = names } });
2529 var dbg_info_buffer = std.ArrayList(u8).init(arena);2514 var dbg_info_buffer = std.ArrayList(u8).init(arena);
2530 try addDbgInfoErrorSet(arena, module, error_ty.toType(), self.target, &dbg_info_buffer);2515 try addDbgInfoErrorSet(module, error_ty.toType(), self.target, &dbg_info_buffer);
25312516
2532 const di_atom_index = try self.createAtom(.di_atom);2517 const di_atom_index = try self.createAtom(.di_atom);
2533 log.debug("updateDeclDebugInfoAllocation in flushModule", .{});2518 log.debug("updateDeclDebugInfoAllocation in flushModule", .{});
...@@ -2644,7 +2629,6 @@ fn genIncludeDirsAndFileNames(self: *Dwarf, arena: Allocator) !struct {...@@ -2644,7 +2629,6 @@ fn genIncludeDirsAndFileNames(self: *Dwarf, arena: Allocator) !struct {
2644}2629}
26452630
2646fn addDbgInfoErrorSet(2631fn addDbgInfoErrorSet(
2647 arena: Allocator,
2648 mod: *Module,2632 mod: *Module,
2649 ty: Type,2633 ty: Type,
2650 target: std.Target,2634 target: std.Target,
...@@ -2658,8 +2642,8 @@ fn addDbgInfoErrorSet(...@@ -2658,8 +2642,8 @@ fn addDbgInfoErrorSet(
2658 const abi_size = Type.anyerror.abiSize(mod);2642 const abi_size = Type.anyerror.abiSize(mod);
2659 try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size);2643 try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size);
2660 // DW.AT.name, DW.FORM.string2644 // DW.AT.name, DW.FORM.string
2661 const name = try ty.nameAllocArena(arena, mod);2645 try ty.print(dbg_info_buffer.writer(), mod);
2662 try dbg_info_buffer.writer().print("{s}\x00", .{name});2646 try dbg_info_buffer.append(0);
26632647
2664 // DW.AT.enumerator2648 // DW.AT.enumerator
2665 const no_error = "(no error)";2649 const no_error = "(no error)";
src/type.zig+35-175
...@@ -2,7 +2,6 @@ const std = @import("std");...@@ -2,7 +2,6 @@ const std = @import("std");
2const builtin = @import("builtin");2const builtin = @import("builtin");
3const Value = @import("value.zig").Value;3const Value = @import("value.zig").Value;
4const assert = std.debug.assert;4const assert = std.debug.assert;
5const Allocator = std.mem.Allocator;
6const Target = std.Target;5const Target = std.Target;
7const Module = @import("Module.zig");6const Module = @import("Module.zig");
8const log = std.log.scoped(.Type);7const log = std.log.scoped(.Type);
...@@ -102,10 +101,10 @@ pub const Type = struct {...@@ -102,10 +101,10 @@ pub const Type = struct {
102 };101 };
103 }102 }
104103
105 pub fn ptrInfoIp(ip: *const InternPool, ty: InternPool.Index) InternPool.Key.PtrType {104 pub fn ptrInfo(ty: Type, mod: *const Module) InternPool.Key.PtrType {
106 return switch (ip.indexToKey(ty)) {105 return switch (mod.intern_pool.indexToKey(ty.toIntern())) {
107 .ptr_type => |p| p,106 .ptr_type => |p| p,
108 .opt_type => |child| switch (ip.indexToKey(child)) {107 .opt_type => |child| switch (mod.intern_pool.indexToKey(child)) {
109 .ptr_type => |p| p,108 .ptr_type => |p| p,
110 else => unreachable,109 else => unreachable,
111 },110 },
...@@ -113,10 +112,6 @@ pub const Type = struct {...@@ -113,10 +112,6 @@ pub const Type = struct {
113 };112 };
114 }113 }
115114
116 pub fn ptrInfo(ty: Type, mod: *const Module) Payload.Pointer.Data {
117 return Payload.Pointer.Data.fromKey(ptrInfoIp(&mod.intern_pool, ty.toIntern()));
118 }
119
120 pub fn eql(a: Type, b: Type, mod: *const Module) bool {115 pub fn eql(a: Type, b: Type, mod: *const Module) bool {
121 _ = mod; // TODO: remove this parameter116 _ = mod; // TODO: remove this parameter
122 // The InternPool data structure hashes based on Key to make interned objects117 // The InternPool data structure hashes based on Key to make interned objects
...@@ -181,15 +176,6 @@ pub const Type = struct {...@@ -181,15 +176,6 @@ pub const Type = struct {
181 return writer.print("{any}", .{start_type.ip_index});176 return writer.print("{any}", .{start_type.ip_index});
182 }177 }
183178
184 pub const nameAllocArena = nameAlloc;
185
186 pub fn nameAlloc(ty: Type, ally: Allocator, module: *Module) Allocator.Error![:0]const u8 {
187 var buffer = std.ArrayList(u8).init(ally);
188 defer buffer.deinit();
189 try ty.print(buffer.writer(), module);
190 return buffer.toOwnedSliceSentinel(0);
191 }
192
193 /// Prints a name suitable for `@typeName`.179 /// Prints a name suitable for `@typeName`.
194 pub fn print(ty: Type, writer: anytype, mod: *Module) @TypeOf(writer).Error!void {180 pub fn print(ty: Type, writer: anytype, mod: *Module) @TypeOf(writer).Error!void {
195 switch (mod.intern_pool.indexToKey(ty.toIntern())) {181 switch (mod.intern_pool.indexToKey(ty.toIntern())) {
...@@ -203,42 +189,44 @@ pub const Type = struct {...@@ -203,42 +189,44 @@ pub const Type = struct {
203 .ptr_type => {189 .ptr_type => {
204 const info = ty.ptrInfo(mod);190 const info = ty.ptrInfo(mod);
205191
206 if (info.sentinel) |s| switch (info.size) {192 if (info.sentinel != .none) switch (info.flags.size) {
207 .One, .C => unreachable,193 .One, .C => unreachable,
208 .Many => try writer.print("[*:{}]", .{s.fmtValue(info.pointee_type, mod)}),194 .Many => try writer.print("[*:{}]", .{info.sentinel.toValue().fmtValue(info.child.toType(), mod)}),
209 .Slice => try writer.print("[:{}]", .{s.fmtValue(info.pointee_type, mod)}),195 .Slice => try writer.print("[:{}]", .{info.sentinel.toValue().fmtValue(info.child.toType(), mod)}),
210 } else switch (info.size) {196 } else switch (info.flags.size) {
211 .One => try writer.writeAll("*"),197 .One => try writer.writeAll("*"),
212 .Many => try writer.writeAll("[*]"),198 .Many => try writer.writeAll("[*]"),
213 .C => try writer.writeAll("[*c]"),199 .C => try writer.writeAll("[*c]"),
214 .Slice => try writer.writeAll("[]"),200 .Slice => try writer.writeAll("[]"),
215 }201 }
216 if (info.@"align" != 0 or info.host_size != 0 or info.vector_index != .none) {202 if (info.flags.alignment != .none or
217 if (info.@"align" != 0) {203 info.packed_offset.host_size != 0 or
218 try writer.print("align({d}", .{info.@"align"});204 info.flags.vector_index != .none)
219 } else {205 {
220 const alignment = info.pointee_type.abiAlignment(mod);206 const alignment = info.flags.alignment.toByteUnitsOptional() orelse
221 try writer.print("align({d}", .{alignment});207 info.child.toType().abiAlignment(mod);
222 }208 try writer.print("align({d}", .{alignment});
223209
224 if (info.bit_offset != 0 or info.host_size != 0) {210 if (info.packed_offset.bit_offset != 0 or info.packed_offset.host_size != 0) {
225 try writer.print(":{d}:{d}", .{ info.bit_offset, info.host_size });211 try writer.print(":{d}:{d}", .{
212 info.packed_offset.bit_offset, info.packed_offset.host_size,
213 });
226 }214 }
227 if (info.vector_index == .runtime) {215 if (info.flags.vector_index == .runtime) {
228 try writer.writeAll(":?");216 try writer.writeAll(":?");
229 } else if (info.vector_index != .none) {217 } else if (info.flags.vector_index != .none) {
230 try writer.print(":{d}", .{@intFromEnum(info.vector_index)});218 try writer.print(":{d}", .{@intFromEnum(info.flags.vector_index)});
231 }219 }
232 try writer.writeAll(") ");220 try writer.writeAll(") ");
233 }221 }
234 if (info.@"addrspace" != .generic) {222 if (info.flags.address_space != .generic) {
235 try writer.print("addrspace(.{s}) ", .{@tagName(info.@"addrspace")});223 try writer.print("addrspace(.{s}) ", .{@tagName(info.flags.address_space)});
236 }224 }
237 if (!info.mutable) try writer.writeAll("const ");225 if (info.flags.is_const) try writer.writeAll("const ");
238 if (info.@"volatile") try writer.writeAll("volatile ");226 if (info.flags.is_volatile) try writer.writeAll("volatile ");
239 if (info.@"allowzero" and info.size != .C) try writer.writeAll("allowzero ");227 if (info.flags.is_allowzero and info.flags.size != .C) try writer.writeAll("allowzero ");
240228
241 try print(info.pointee_type, writer, mod);229 try print(info.child.toType(), writer, mod);
242 return;230 return;
243 },231 },
244 .array_type => |array_type| {232 .array_type => |array_type| {
...@@ -1035,9 +1023,8 @@ pub const Type = struct {...@@ -1035,9 +1023,8 @@ pub const Type = struct {
1035 else => |e| return e,1023 else => |e| return e,
1036 })) continue;1024 })) continue;
10371025
1038 const field_align = if (field.abi_align != 0)1026 const field_align = @intCast(u32, field.abi_align.toByteUnitsOptional() orelse
1039 field.abi_align1027 switch (try field.ty.abiAlignmentAdvanced(mod, strat)) {
1040 else switch (try field.ty.abiAlignmentAdvanced(mod, strat)) {
1041 .scalar => |a| a,1028 .scalar => |a| a,
1042 .val => switch (strat) {1029 .val => switch (strat) {
1043 .eager => unreachable, // struct layout not resolved1030 .eager => unreachable, // struct layout not resolved
...@@ -1047,7 +1034,7 @@ pub const Type = struct {...@@ -1047,7 +1034,7 @@ pub const Type = struct {
1047 .storage = .{ .lazy_align = ty.toIntern() },1034 .storage = .{ .lazy_align = ty.toIntern() },
1048 } })).toValue() },1035 } })).toValue() },
1049 },1036 },
1050 };1037 });
1051 big_align = @max(big_align, field_align);1038 big_align = @max(big_align, field_align);
10521039
1053 // This logic is duplicated in Module.Struct.Field.alignment.1040 // This logic is duplicated in Module.Struct.Field.alignment.
...@@ -1242,9 +1229,8 @@ pub const Type = struct {...@@ -1242,9 +1229,8 @@ pub const Type = struct {
1242 else => |e| return e,1229 else => |e| return e,
1243 })) continue;1230 })) continue;
12441231
1245 const field_align = if (field.abi_align != 0)1232 const field_align = @intCast(u32, field.abi_align.toByteUnitsOptional() orelse
1246 field.abi_align1233 switch (try field.ty.abiAlignmentAdvanced(mod, strat)) {
1247 else switch (try field.ty.abiAlignmentAdvanced(mod, strat)) {
1248 .scalar => |a| a,1234 .scalar => |a| a,
1249 .val => switch (strat) {1235 .val => switch (strat) {
1250 .eager => unreachable, // struct layout not resolved1236 .eager => unreachable, // struct layout not resolved
...@@ -1254,7 +1240,7 @@ pub const Type = struct {...@@ -1254,7 +1240,7 @@ pub const Type = struct {
1254 .storage = .{ .lazy_align = ty.toIntern() },1240 .storage = .{ .lazy_align = ty.toIntern() },
1255 } })).toValue() },1241 } })).toValue() },
1256 },1242 },
1257 };1243 });
1258 max_align = @max(max_align, field_align);1244 max_align = @max(max_align, field_align);
1259 }1245 }
1260 return AbiAlignmentAdvanced{ .scalar = max_align };1246 return AbiAlignmentAdvanced{ .scalar = max_align };
...@@ -1883,7 +1869,7 @@ pub const Type = struct {...@@ -1883,7 +1869,7 @@ pub const Type = struct {
1883 if (ty.isPtrLikeOptional(mod)) {1869 if (ty.isPtrLikeOptional(mod)) {
1884 return true;1870 return true;
1885 }1871 }
1886 return ty.ptrInfo(mod).@"allowzero";1872 return ty.ptrInfo(mod).flags.is_allowzero;
1887 }1873 }
18881874
1889 /// See also `isPtrLikeOptional`.1875 /// See also `isPtrLikeOptional`.
...@@ -3345,58 +3331,6 @@ pub const Type = struct {...@@ -3345,58 +3331,6 @@ pub const Type = struct {
3345 };3331 };
3346 }3332 }
33473333
3348 pub const Payload = struct {
3349 /// TODO: remove this data structure since we have `InternPool.Key.PtrType`.
3350 pub const Pointer = struct {
3351 pub const Data = struct {
3352 pointee_type: Type,
3353 sentinel: ?Value = null,
3354 /// If zero use pointee_type.abiAlignment()
3355 /// When creating pointer types, if alignment is equal to pointee type
3356 /// abi alignment, this value should be set to 0 instead.
3357 @"align": u32 = 0,
3358 /// See src/target.zig defaultAddressSpace function for how to obtain
3359 /// an appropriate value for this field.
3360 @"addrspace": std.builtin.AddressSpace,
3361 bit_offset: u16 = 0,
3362 /// If this is non-zero it means the pointer points to a sub-byte
3363 /// range of data, which is backed by a "host integer" with this
3364 /// number of bytes.
3365 /// When host_size=pointee_abi_size and bit_offset=0, this must be
3366 /// represented with host_size=0 instead.
3367 host_size: u16 = 0,
3368 vector_index: VectorIndex = .none,
3369 @"allowzero": bool = false,
3370 mutable: bool = true, // TODO rename this to const, not mutable
3371 @"volatile": bool = false,
3372 size: std.builtin.Type.Pointer.Size = .One,
3373
3374 pub const VectorIndex = InternPool.Key.PtrType.VectorIndex;
3375
3376 pub fn alignment(data: Data, mod: *Module) u32 {
3377 if (data.@"align" != 0) return data.@"align";
3378 return abiAlignment(data.pointee_type, mod);
3379 }
3380
3381 pub fn fromKey(p: InternPool.Key.PtrType) Data {
3382 return .{
3383 .pointee_type = p.child.toType(),
3384 .sentinel = if (p.sentinel != .none) p.sentinel.toValue() else null,
3385 .@"align" = @intCast(u32, p.flags.alignment.toByteUnits(0)),
3386 .@"addrspace" = p.flags.address_space,
3387 .bit_offset = p.packed_offset.bit_offset,
3388 .host_size = p.packed_offset.host_size,
3389 .vector_index = p.flags.vector_index,
3390 .@"allowzero" = p.flags.is_allowzero,
3391 .mutable = !p.flags.is_const,
3392 .@"volatile" = p.flags.is_volatile,
3393 .size = p.flags.size,
3394 };
3395 }
3396 };
3397 };
3398 };
3399
3400 pub const @"u1": Type = .{ .ip_index = .u1_type };3334 pub const @"u1": Type = .{ .ip_index = .u1_type };
3401 pub const @"u8": Type = .{ .ip_index = .u8_type };3335 pub const @"u8": Type = .{ .ip_index = .u8_type };
3402 pub const @"u16": Type = .{ .ip_index = .u16_type };3336 pub const @"u16": Type = .{ .ip_index = .u16_type };
...@@ -3454,80 +3388,6 @@ pub const Type = struct {...@@ -3454,80 +3388,6 @@ pub const Type = struct {
34543388
3455 pub const err_int = Type.u16;3389 pub const err_int = Type.u16;
34563390
3457 pub fn ptr(arena: Allocator, mod: *Module, data: Payload.Pointer.Data) !Type {
3458 // TODO: update callsites of this function to directly call mod.ptrType
3459 // and then delete this function.
3460 _ = arena;
3461
3462 var d = data;
3463
3464 // Canonicalize non-zero alignment. If it matches the ABI alignment of the pointee
3465 // type, we change it to 0 here. If this causes an assertion trip because the
3466 // pointee type needs to be resolved more, that needs to be done before calling
3467 // this ptr() function.
3468 if (d.@"align" != 0) canonicalize: {
3469 if (!d.pointee_type.layoutIsResolved(mod)) break :canonicalize;
3470 if (d.@"align" == d.pointee_type.abiAlignment(mod)) {
3471 d.@"align" = 0;
3472 }
3473 }
3474
3475 // Canonicalize host_size. If it matches the bit size of the pointee type,
3476 // we change it to 0 here. If this causes an assertion trip, the pointee type
3477 // needs to be resolved before calling this ptr() function.
3478 if (d.host_size != 0) {
3479 assert(d.bit_offset < d.host_size * 8);
3480 if (d.host_size * 8 == d.pointee_type.bitSize(mod)) {
3481 assert(d.bit_offset == 0);
3482 d.host_size = 0;
3483 }
3484 }
3485
3486 return mod.ptrType(.{
3487 .child = d.pointee_type.ip_index,
3488 .sentinel = if (d.sentinel) |s| s.ip_index else .none,
3489 .flags = .{
3490 .alignment = InternPool.Alignment.fromByteUnits(d.@"align"),
3491 .vector_index = d.vector_index,
3492 .size = d.size,
3493 .is_const = !d.mutable,
3494 .is_volatile = d.@"volatile",
3495 .is_allowzero = d.@"allowzero",
3496 .address_space = d.@"addrspace",
3497 },
3498 .packed_offset = .{
3499 .host_size = d.host_size,
3500 .bit_offset = d.bit_offset,
3501 },
3502 });
3503 }
3504
3505 pub fn array(
3506 arena: Allocator,
3507 len: u64,
3508 sent: ?Value,
3509 elem_type: Type,
3510 mod: *Module,
3511 ) Allocator.Error!Type {
3512 // TODO: update callsites of this function to directly call mod.arrayType
3513 // and then delete this function.
3514 _ = arena;
3515
3516 return mod.arrayType(.{
3517 .len = len,
3518 .child = elem_type.ip_index,
3519 .sentinel = if (sent) |s| s.ip_index else .none,
3520 });
3521 }
3522
3523 pub fn optional(arena: Allocator, child_type: Type, mod: *Module) Allocator.Error!Type {
3524 // TODO: update callsites of this function to directly call
3525 // mod.optionalType and then delete this function.
3526 _ = arena;
3527
3528 return mod.optionalType(child_type.ip_index);
3529 }
3530
3531 pub fn smallestUnsignedBits(max: u64) u16 {3391 pub fn smallestUnsignedBits(max: u64) u16 {
3532 if (max == 0) return 0;3392 if (max == 0) return 0;
3533 const base = std.math.log2(max);3393 const base = std.math.log2(max);