authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-03-22 00:23:54-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-03-22 15:45:58-07:00
log593130ce0a4b06185fcb4806f8330857a1da9f92
treeae30c61a06e6cecb97cc760dc6acd0cbfb83c162
parentb74f2924102fe06addb688dc5fd039dc2756f619

stage2: lazy `@alignOf`

Add a `target` parameter to every function that deals with Type and Value.

24 files changed, 1570 insertions(+), 1053 deletions(-)

src/Compilation.zig+3-1
...@@ -2781,7 +2781,9 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress...@@ -2781,7 +2781,9 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress
2781 .error_msg = null,2781 .error_msg = null,
2782 .decl = decl,2782 .decl = decl,
2783 .fwd_decl = fwd_decl.toManaged(gpa),2783 .fwd_decl = fwd_decl.toManaged(gpa),
2784 .typedefs = c_codegen.TypedefMap.init(gpa),2784 .typedefs = c_codegen.TypedefMap.initContext(gpa, .{
2785 .target = comp.getTarget(),
2786 }),
2785 .typedefs_arena = typedefs_arena.allocator(),2787 .typedefs_arena = typedefs_arena.allocator(),
2786 };2788 };
2787 defer dg.fwd_decl.deinit();2789 defer dg.fwd_decl.deinit();
src/Module.zig+19-33
...@@ -146,6 +146,8 @@ const MonomorphedFuncsSet = std.HashMapUnmanaged(...@@ -146,6 +146,8 @@ const MonomorphedFuncsSet = std.HashMapUnmanaged(
146);146);
147147
148const MonomorphedFuncsContext = struct {148const MonomorphedFuncsContext = struct {
149 target: Target,
150
149 pub fn eql(ctx: @This(), a: *Fn, b: *Fn) bool {151 pub fn eql(ctx: @This(), a: *Fn, b: *Fn) bool {
150 _ = ctx;152 _ = ctx;
151 return a == b;153 return a == b;
...@@ -153,7 +155,6 @@ const MonomorphedFuncsContext = struct {...@@ -153,7 +155,6 @@ const MonomorphedFuncsContext = struct {
153155
154 /// Must match `Sema.GenericCallAdapter.hash`.156 /// Must match `Sema.GenericCallAdapter.hash`.
155 pub fn hash(ctx: @This(), key: *Fn) u64 {157 pub fn hash(ctx: @This(), key: *Fn) u64 {
156 _ = ctx;
157 var hasher = std.hash.Wyhash.init(0);158 var hasher = std.hash.Wyhash.init(0);
158159
159 // The generic function Decl is guaranteed to be the first dependency160 // The generic function Decl is guaranteed to be the first dependency
...@@ -168,7 +169,7 @@ const MonomorphedFuncsContext = struct {...@@ -168,7 +169,7 @@ const MonomorphedFuncsContext = struct {
168 const generic_ty_info = generic_owner_decl.ty.fnInfo();169 const generic_ty_info = generic_owner_decl.ty.fnInfo();
169 for (generic_ty_info.param_types) |param_ty, i| {170 for (generic_ty_info.param_types) |param_ty, i| {
170 if (generic_ty_info.paramIsComptime(i) and param_ty.tag() != .generic_poison) {171 if (generic_ty_info.paramIsComptime(i) and param_ty.tag() != .generic_poison) {
171 comptime_args[i].val.hash(param_ty, &hasher);172 comptime_args[i].val.hash(param_ty, &hasher, ctx.target);
172 }173 }
173 }174 }
174175
...@@ -184,6 +185,8 @@ pub const MemoizedCallSet = std.HashMapUnmanaged(...@@ -184,6 +185,8 @@ pub const MemoizedCallSet = std.HashMapUnmanaged(
184);185);
185186
186pub const MemoizedCall = struct {187pub const MemoizedCall = struct {
188 target: std.Target,
189
187 pub const Key = struct {190 pub const Key = struct {
188 func: *Fn,191 func: *Fn,
189 args: []TypedValue,192 args: []TypedValue,
...@@ -195,14 +198,12 @@ pub const MemoizedCall = struct {...@@ -195,14 +198,12 @@ pub const MemoizedCall = struct {
195 };198 };
196199
197 pub fn eql(ctx: @This(), a: Key, b: Key) bool {200 pub fn eql(ctx: @This(), a: Key, b: Key) bool {
198 _ = ctx;
199
200 if (a.func != b.func) return false;201 if (a.func != b.func) return false;
201202
202 assert(a.args.len == b.args.len);203 assert(a.args.len == b.args.len);
203 for (a.args) |a_arg, arg_i| {204 for (a.args) |a_arg, arg_i| {
204 const b_arg = b.args[arg_i];205 const b_arg = b.args[arg_i];
205 if (!a_arg.eql(b_arg)) {206 if (!a_arg.eql(b_arg, ctx.target)) {
206 return false;207 return false;
207 }208 }
208 }209 }
...@@ -212,8 +213,6 @@ pub const MemoizedCall = struct {...@@ -212,8 +213,6 @@ pub const MemoizedCall = struct {
212213
213 /// Must match `Sema.GenericCallAdapter.hash`.214 /// Must match `Sema.GenericCallAdapter.hash`.
214 pub fn hash(ctx: @This(), key: Key) u64 {215 pub fn hash(ctx: @This(), key: Key) u64 {
215 _ = ctx;
216
217 var hasher = std.hash.Wyhash.init(0);216 var hasher = std.hash.Wyhash.init(0);
218217
219 // The generic function Decl is guaranteed to be the first dependency218 // The generic function Decl is guaranteed to be the first dependency
...@@ -223,7 +222,7 @@ pub const MemoizedCall = struct {...@@ -223,7 +222,7 @@ pub const MemoizedCall = struct {
223 // This logic must be kept in sync with the logic in `analyzeCall` that222 // This logic must be kept in sync with the logic in `analyzeCall` that
224 // computes the hash.223 // computes the hash.
225 for (key.args) |arg| {224 for (key.args) |arg| {
226 arg.hash(&hasher);225 arg.hash(&hasher, ctx.target);
227 }226 }
228227
229 return hasher.final();228 return hasher.final();
...@@ -1230,7 +1229,7 @@ pub const Union = struct {...@@ -1230,7 +1229,7 @@ pub const Union = struct {
1230 if (field.abi_align == 0) {1229 if (field.abi_align == 0) {
1231 break :a field.ty.abiAlignment(target);1230 break :a field.ty.abiAlignment(target);
1232 } else {1231 } else {
1233 break :a @intCast(u32, field.abi_align.toUnsignedInt());1232 break :a field.abi_align;
1234 }1233 }
1235 };1234 };
1236 if (field_align > most_alignment) {1235 if (field_align > most_alignment) {
...@@ -3877,6 +3876,7 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {...@@ -3877,6 +3876,7 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
3877 const bytes = try sema.resolveConstString(&block_scope, src, linksection_ref);3876 const bytes = try sema.resolveConstString(&block_scope, src, linksection_ref);
3878 break :blk (try decl_arena_allocator.dupeZ(u8, bytes)).ptr;3877 break :blk (try decl_arena_allocator.dupeZ(u8, bytes)).ptr;
3879 };3878 };
3879 const target = sema.mod.getTarget();
3880 const address_space = blk: {3880 const address_space = blk: {
3881 const addrspace_ctx: Sema.AddressSpaceContext = switch (decl_tv.val.tag()) {3881 const addrspace_ctx: Sema.AddressSpaceContext = switch (decl_tv.val.tag()) {
3882 .function, .extern_fn => .function,3882 .function, .extern_fn => .function,
...@@ -3886,9 +3886,9 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {...@@ -3886,9 +3886,9 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
38863886
3887 break :blk switch (decl.zirAddrspaceRef()) {3887 break :blk switch (decl.zirAddrspaceRef()) {
3888 .none => switch (addrspace_ctx) {3888 .none => switch (addrspace_ctx) {
3889 .function => target_util.defaultAddressSpace(sema.mod.getTarget(), .function),3889 .function => target_util.defaultAddressSpace(target, .function),
3890 .variable => target_util.defaultAddressSpace(sema.mod.getTarget(), .global_mutable),3890 .variable => target_util.defaultAddressSpace(target, .global_mutable),
3891 .constant => target_util.defaultAddressSpace(sema.mod.getTarget(), .global_constant),3891 .constant => target_util.defaultAddressSpace(target, .global_constant),
3892 else => unreachable,3892 else => unreachable,
3893 },3893 },
3894 else => |addrspace_ref| try sema.analyzeAddrspace(&block_scope, src, addrspace_ref, addrspace_ctx),3894 else => |addrspace_ref| try sema.analyzeAddrspace(&block_scope, src, addrspace_ref, addrspace_ctx),
...@@ -3904,13 +3904,15 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {...@@ -3904,13 +3904,15 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
39043904
3905 if (decl.is_usingnamespace) {3905 if (decl.is_usingnamespace) {
3906 const ty_ty = Type.initTag(.type);3906 const ty_ty = Type.initTag(.type);
3907 if (!decl_tv.ty.eql(ty_ty)) {3907 if (!decl_tv.ty.eql(ty_ty, target)) {
3908 return sema.fail(&block_scope, src, "expected type, found {}", .{decl_tv.ty});3908 return sema.fail(&block_scope, src, "expected type, found {}", .{
3909 decl_tv.ty.fmt(target),
3910 });
3909 }3911 }
3910 var buffer: Value.ToTypeBuffer = undefined;3912 var buffer: Value.ToTypeBuffer = undefined;
3911 const ty = decl_tv.val.toType(&buffer);3913 const ty = decl_tv.val.toType(&buffer);
3912 if (ty.getNamespace() == null) {3914 if (ty.getNamespace() == null) {
3913 return sema.fail(&block_scope, src, "type {} has no namespace", .{ty});3915 return sema.fail(&block_scope, src, "type {} has no namespace", .{ty.fmt(target)});
3914 }3916 }
39153917
3916 decl.ty = ty_ty;3918 decl.ty = ty_ty;
...@@ -3937,7 +3939,7 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {...@@ -3937,7 +3939,7 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
39373939
3938 if (decl.has_tv) {3940 if (decl.has_tv) {
3939 prev_type_has_bits = decl.ty.isFnOrHasRuntimeBits();3941 prev_type_has_bits = decl.ty.isFnOrHasRuntimeBits();
3940 type_changed = !decl.ty.eql(decl_tv.ty);3942 type_changed = !decl.ty.eql(decl_tv.ty, target);
3941 if (decl.getFunction()) |prev_func| {3943 if (decl.getFunction()) |prev_func| {
3942 prev_is_inline = prev_func.state == .inline_only;3944 prev_is_inline = prev_func.state == .inline_only;
3943 }3945 }
...@@ -3986,7 +3988,7 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {...@@ -3986,7 +3988,7 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
3986 }3988 }
3987 var type_changed = true;3989 var type_changed = true;
3988 if (decl.has_tv) {3990 if (decl.has_tv) {
3989 type_changed = !decl.ty.eql(decl_tv.ty);3991 type_changed = !decl.ty.eql(decl_tv.ty, target);
3990 decl.clearValues(gpa);3992 decl.clearValues(gpa);
3991 }3993 }
39923994
...@@ -5054,22 +5056,6 @@ pub fn errNoteNonLazy(...@@ -5054,22 +5056,6 @@ pub fn errNoteNonLazy(
5054 };5056 };
5055}5057}
50565058
5057pub fn errorUnionType(
5058 arena: Allocator,
5059 error_set: Type,
5060 payload: Type,
5061) Allocator.Error!Type {
5062 assert(error_set.zigTypeTag() == .ErrorSet);
5063 if (error_set.eql(Type.initTag(.anyerror)) and payload.eql(Type.initTag(.void))) {
5064 return Type.initTag(.anyerror_void_error_union);
5065 }
5066
5067 return Type.Tag.error_union.create(arena, .{
5068 .error_set = error_set,
5069 .payload = payload,
5070 });
5071}
5072
5073pub fn getTarget(mod: Module) Target {5059pub fn getTarget(mod: Module) Target {
5074 return mod.comp.bin_file.options.target;5060 return mod.comp.bin_file.options.target;
5075}5061}
src/RangeSet.zig+22-9
...@@ -6,6 +6,7 @@ const RangeSet = @This();...@@ -6,6 +6,7 @@ const RangeSet = @This();
6const SwitchProngSrc = @import("Module.zig").SwitchProngSrc;6const SwitchProngSrc = @import("Module.zig").SwitchProngSrc;
77
8ranges: std.ArrayList(Range),8ranges: std.ArrayList(Range),
9target: std.Target,
910
10pub const Range = struct {11pub const Range = struct {
11 first: Value,12 first: Value,
...@@ -13,9 +14,10 @@ pub const Range = struct {...@@ -13,9 +14,10 @@ pub const Range = struct {
13 src: SwitchProngSrc,14 src: SwitchProngSrc,
14};15};
1516
16pub fn init(allocator: std.mem.Allocator) RangeSet {17pub fn init(allocator: std.mem.Allocator, target: std.Target) RangeSet {
17 return .{18 return .{
18 .ranges = std.ArrayList(Range).init(allocator),19 .ranges = std.ArrayList(Range).init(allocator),
20 .target = target,
19 };21 };
20}22}
2123
...@@ -30,8 +32,12 @@ pub fn add(...@@ -30,8 +32,12 @@ pub fn add(
30 ty: Type,32 ty: Type,
31 src: SwitchProngSrc,33 src: SwitchProngSrc,
32) !?SwitchProngSrc {34) !?SwitchProngSrc {
35 const target = self.target;
36
33 for (self.ranges.items) |range| {37 for (self.ranges.items) |range| {
34 if (last.compare(.gte, range.first, ty) and first.compare(.lte, range.last, ty)) {38 if (last.compare(.gte, range.first, ty, target) and
39 first.compare(.lte, range.last, ty, target))
40 {
35 return range.src; // They overlap.41 return range.src; // They overlap.
36 }42 }
37 }43 }
...@@ -43,19 +49,26 @@ pub fn add(...@@ -43,19 +49,26 @@ pub fn add(
43 return null;49 return null;
44}50}
4551
52const LessThanContext = struct { ty: Type, target: std.Target };
53
46/// Assumes a and b do not overlap54/// Assumes a and b do not overlap
47fn lessThan(ty: Type, a: Range, b: Range) bool {55fn lessThan(ctx: LessThanContext, a: Range, b: Range) bool {
48 return a.first.compare(.lt, b.first, ty);56 return a.first.compare(.lt, b.first, ctx.ty, ctx.target);
49}57}
5058
51pub fn spans(self: *RangeSet, first: Value, last: Value, ty: Type) !bool {59pub fn spans(self: *RangeSet, first: Value, last: Value, ty: Type) !bool {
52 if (self.ranges.items.len == 0)60 if (self.ranges.items.len == 0)
53 return false;61 return false;
5462
55 std.sort.sort(Range, self.ranges.items, ty, lessThan);63 const target = self.target;
64
65 std.sort.sort(Range, self.ranges.items, LessThanContext{
66 .ty = ty,
67 .target = target,
68 }, lessThan);
5669
57 if (!self.ranges.items[0].first.eql(first, ty) or70 if (!self.ranges.items[0].first.eql(first, ty, target) or
58 !self.ranges.items[self.ranges.items.len - 1].last.eql(last, ty))71 !self.ranges.items[self.ranges.items.len - 1].last.eql(last, ty, target))
59 {72 {
60 return false;73 return false;
61 }74 }
...@@ -71,10 +84,10 @@ pub fn spans(self: *RangeSet, first: Value, last: Value, ty: Type) !bool {...@@ -71,10 +84,10 @@ pub fn spans(self: *RangeSet, first: Value, last: Value, ty: Type) !bool {
71 const prev = self.ranges.items[i];84 const prev = self.ranges.items[i];
7285
73 // prev.last + 1 == cur.first86 // prev.last + 1 == cur.first
74 try counter.copy(prev.last.toBigInt(&space));87 try counter.copy(prev.last.toBigInt(&space, target));
75 try counter.addScalar(counter.toConst(), 1);88 try counter.addScalar(counter.toConst(), 1);
7689
77 const cur_start_int = cur.first.toBigInt(&space);90 const cur_start_int = cur.first.toBigInt(&space, target);
78 if (!cur_start_int.eq(counter.toConst())) {91 if (!cur_start_int.eq(counter.toConst())) {
79 return false;92 return false;
80 }93 }
src/Sema.zig+499-349
...@@ -1303,7 +1303,8 @@ pub fn resolveConstString(...@@ -1303,7 +1303,8 @@ pub fn resolveConstString(
1303 const wanted_type = Type.initTag(.const_slice_u8);1303 const wanted_type = Type.initTag(.const_slice_u8);
1304 const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src);1304 const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src);
1305 const val = try sema.resolveConstValue(block, src, coerced_inst);1305 const val = try sema.resolveConstValue(block, src, coerced_inst);
1306 return val.toAllocatedBytes(wanted_type, sema.arena);1306 const target = sema.mod.getTarget();
1307 return val.toAllocatedBytes(wanted_type, sema.arena, target);
1307}1308}
13081309
1309pub fn resolveType(sema: *Sema, block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref) !Type {1310pub fn resolveType(sema: *Sema, block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref) !Type {
...@@ -1457,19 +1458,29 @@ fn failWithDivideByZero(sema: *Sema, block: *Block, src: LazySrcLoc) CompileErro...@@ -1457,19 +1458,29 @@ fn failWithDivideByZero(sema: *Sema, block: *Block, src: LazySrcLoc) CompileErro
1457}1458}
14581459
1459fn failWithModRemNegative(sema: *Sema, block: *Block, src: LazySrcLoc, lhs_ty: Type, rhs_ty: Type) CompileError {1460fn failWithModRemNegative(sema: *Sema, block: *Block, src: LazySrcLoc, lhs_ty: Type, rhs_ty: Type) CompileError {
1460 return sema.fail(block, src, "remainder division with '{}' and '{}': signed integers and floats must use @rem or @mod", .{ lhs_ty, rhs_ty });1461 const target = sema.mod.getTarget();
1462 return sema.fail(block, src, "remainder division with '{}' and '{}': signed integers and floats must use @rem or @mod", .{
1463 lhs_ty.fmt(target), rhs_ty.fmt(target),
1464 });
1461}1465}
14621466
1463fn failWithExpectedOptionalType(sema: *Sema, block: *Block, src: LazySrcLoc, optional_ty: Type) CompileError {1467fn failWithExpectedOptionalType(sema: *Sema, block: *Block, src: LazySrcLoc, optional_ty: Type) CompileError {
1464 return sema.fail(block, src, "expected optional type, found {}", .{optional_ty});1468 const target = sema.mod.getTarget();
1469 return sema.fail(block, src, "expected optional type, found {}", .{optional_ty.fmt(target)});
1465}1470}
14661471
1467fn failWithArrayInitNotSupported(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError {1472fn failWithArrayInitNotSupported(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError {
1468 return sema.fail(block, src, "type '{}' does not support array initialization syntax", .{ty});1473 const target = sema.mod.getTarget();
1474 return sema.fail(block, src, "type '{}' does not support array initialization syntax", .{
1475 ty.fmt(target),
1476 });
1469}1477}
14701478
1471fn failWithStructInitNotSupported(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError {1479fn failWithStructInitNotSupported(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError {
1472 return sema.fail(block, src, "type '{}' does not support struct initialization syntax", .{ty});1480 const target = sema.mod.getTarget();
1481 return sema.fail(block, src, "type '{}' does not support struct initialization syntax", .{
1482 ty.fmt(target),
1483 });
1473}1484}
14741485
1475fn failWithErrorSetCodeMissing(1486fn failWithErrorSetCodeMissing(
...@@ -1479,8 +1490,9 @@ fn failWithErrorSetCodeMissing(...@@ -1479,8 +1490,9 @@ fn failWithErrorSetCodeMissing(
1479 dest_err_set_ty: Type,1490 dest_err_set_ty: Type,
1480 src_err_set_ty: Type,1491 src_err_set_ty: Type,
1481) CompileError {1492) CompileError {
1493 const target = sema.mod.getTarget();
1482 return sema.fail(block, src, "expected type '{}', found type '{}'", .{1494 return sema.fail(block, src, "expected type '{}', found type '{}'", .{
1483 dest_err_set_ty, src_err_set_ty,1495 dest_err_set_ty.fmt(target), src_err_set_ty.fmt(target),
1484 });1496 });
1485}1497}
14861498
...@@ -1578,8 +1590,8 @@ fn resolveInt(...@@ -1578,8 +1590,8 @@ fn resolveInt(
1578 const air_inst = sema.resolveInst(zir_ref);1590 const air_inst = sema.resolveInst(zir_ref);
1579 const coerced = try sema.coerce(block, dest_ty, air_inst, src);1591 const coerced = try sema.coerce(block, dest_ty, air_inst, src);
1580 const val = try sema.resolveConstValue(block, src, coerced);1592 const val = try sema.resolveConstValue(block, src, coerced);
15811593 const target = sema.mod.getTarget();
1582 return val.toUnsignedInt();1594 return val.toUnsignedInt(target);
1583}1595}
15841596
1585// Returns a compile error if the value has tag `variable`. See `resolveInstValue` for1597// Returns a compile error if the value has tag `variable`. See `resolveInstValue` for
...@@ -1864,6 +1876,7 @@ fn createTypeName(...@@ -1864,6 +1876,7 @@ fn createTypeName(
1864 },1876 },
1865 .parent => return sema.gpa.dupeZ(u8, mem.sliceTo(block.src_decl.name, 0)),1877 .parent => return sema.gpa.dupeZ(u8, mem.sliceTo(block.src_decl.name, 0)),
1866 .func => {1878 .func => {
1879 const target = sema.mod.getTarget();
1867 const fn_info = sema.code.getFnInfo(sema.func.?.zir_body_inst);1880 const fn_info = sema.code.getFnInfo(sema.func.?.zir_body_inst);
1868 const zir_tags = sema.code.instructions.items(.tag);1881 const zir_tags = sema.code.instructions.items(.tag);
18691882
...@@ -1881,7 +1894,7 @@ fn createTypeName(...@@ -1881,7 +1894,7 @@ fn createTypeName(
1881 const arg_val = sema.resolveConstMaybeUndefVal(block, .unneeded, arg) catch unreachable;1894 const arg_val = sema.resolveConstMaybeUndefVal(block, .unneeded, arg) catch unreachable;
18821895
1883 if (arg_i != 0) try buf.appendSlice(",");1896 if (arg_i != 0) try buf.appendSlice(",");
1884 try buf.writer().print("{}", .{arg_val.fmtValue(sema.typeOf(arg))});1897 try buf.writer().print("{}", .{arg_val.fmtValue(sema.typeOf(arg), target)});
18851898
1886 arg_i += 1;1899 arg_i += 1;
1887 continue;1900 continue;
...@@ -2045,6 +2058,7 @@ fn zirEnumDecl(...@@ -2045,6 +2058,7 @@ fn zirEnumDecl(
2045 enum_obj.tag_ty_inferred = true;2058 enum_obj.tag_ty_inferred = true;
2046 }2059 }
2047 }2060 }
2061 const target = mod.getTarget();
20482062
2049 try enum_obj.fields.ensureTotalCapacity(new_decl_arena_allocator, fields_len);2063 try enum_obj.fields.ensureTotalCapacity(new_decl_arena_allocator, fields_len);
2050 const any_values = for (sema.code.extra[body_end..][0..bit_bags_count]) |bag| {2064 const any_values = for (sema.code.extra[body_end..][0..bit_bags_count]) |bag| {
...@@ -2053,6 +2067,7 @@ fn zirEnumDecl(...@@ -2053,6 +2067,7 @@ fn zirEnumDecl(
2053 if (any_values) {2067 if (any_values) {
2054 try enum_obj.values.ensureTotalCapacityContext(new_decl_arena_allocator, fields_len, .{2068 try enum_obj.values.ensureTotalCapacityContext(new_decl_arena_allocator, fields_len, .{
2055 .ty = enum_obj.tag_ty,2069 .ty = enum_obj.tag_ty,
2070 .target = target,
2056 });2071 });
2057 }2072 }
20582073
...@@ -2102,16 +2117,18 @@ fn zirEnumDecl(...@@ -2102,16 +2117,18 @@ fn zirEnumDecl(
2102 const copied_tag_val = try tag_val.copy(new_decl_arena_allocator);2117 const copied_tag_val = try tag_val.copy(new_decl_arena_allocator);
2103 enum_obj.values.putAssumeCapacityNoClobberContext(copied_tag_val, {}, .{2118 enum_obj.values.putAssumeCapacityNoClobberContext(copied_tag_val, {}, .{
2104 .ty = enum_obj.tag_ty,2119 .ty = enum_obj.tag_ty,
2120 .target = target,
2105 });2121 });
2106 } else if (any_values) {2122 } else if (any_values) {
2107 const tag_val = if (last_tag_val) |val|2123 const tag_val = if (last_tag_val) |val|
2108 try val.intAdd(Value.one, enum_obj.tag_ty, sema.arena)2124 try val.intAdd(Value.one, enum_obj.tag_ty, sema.arena, target)
2109 else2125 else
2110 Value.zero;2126 Value.zero;
2111 last_tag_val = tag_val;2127 last_tag_val = tag_val;
2112 const copied_tag_val = try tag_val.copy(new_decl_arena_allocator);2128 const copied_tag_val = try tag_val.copy(new_decl_arena_allocator);
2113 enum_obj.values.putAssumeCapacityNoClobberContext(copied_tag_val, {}, .{2129 enum_obj.values.putAssumeCapacityNoClobberContext(copied_tag_val, {}, .{
2114 .ty = enum_obj.tag_ty,2130 .ty = enum_obj.tag_ty,
2131 .target = target,
2115 });2132 });
2116 }2133 }
2117 }2134 }
...@@ -2417,13 +2434,14 @@ fn zirIndexablePtrLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE...@@ -2417,13 +2434,14 @@ fn zirIndexablePtrLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
2417 else2434 else
2418 object_ty;2435 object_ty;
24192436
2437 const target = sema.mod.getTarget();
2420 if (!array_ty.isIndexable()) {2438 if (!array_ty.isIndexable()) {
2421 const msg = msg: {2439 const msg = msg: {
2422 const msg = try sema.errMsg(2440 const msg = try sema.errMsg(
2423 block,2441 block,
2424 src,2442 src,
2425 "type '{}' does not support indexing",2443 "type '{}' does not support indexing",
2426 .{array_ty},2444 .{array_ty.fmt(target)},
2427 );2445 );
2428 errdefer msg.destroy(sema.gpa);2446 errdefer msg.destroy(sema.gpa);
2429 try sema.errNote(2447 try sema.errNote(
...@@ -3346,8 +3364,9 @@ fn failWithBadMemberAccess(...@@ -3346,8 +3364,9 @@ fn failWithBadMemberAccess(
3346 else => unreachable,3364 else => unreachable,
3347 };3365 };
3348 const msg = msg: {3366 const msg = msg: {
3367 const target = sema.mod.getTarget();
3349 const msg = try sema.errMsg(block, field_src, "{s} '{}' has no member named '{s}'", .{3368 const msg = try sema.errMsg(block, field_src, "{s} '{}' has no member named '{s}'", .{
3350 kw_name, agg_ty, field_name,3369 kw_name, agg_ty.fmt(target), field_name,
3351 });3370 });
3352 errdefer msg.destroy(sema.gpa);3371 errdefer msg.destroy(sema.gpa);
3353 try sema.addDeclaredHereNote(msg, agg_ty);3372 try sema.addDeclaredHereNote(msg, agg_ty);
...@@ -3680,6 +3699,7 @@ fn zirCompileLog(...@@ -3680,6 +3699,7 @@ fn zirCompileLog(
3680 const src_node = extra.data.src_node;3699 const src_node = extra.data.src_node;
3681 const src: LazySrcLoc = .{ .node_offset = src_node };3700 const src: LazySrcLoc = .{ .node_offset = src_node };
3682 const args = sema.code.refSlice(extra.end, extended.small);3701 const args = sema.code.refSlice(extra.end, extended.small);
3702 const target = sema.mod.getTarget();
36833703
3684 for (args) |arg_ref, i| {3704 for (args) |arg_ref, i| {
3685 if (i != 0) try writer.print(", ", .{});3705 if (i != 0) try writer.print(", ", .{});
...@@ -3687,9 +3707,11 @@ fn zirCompileLog(...@@ -3687,9 +3707,11 @@ fn zirCompileLog(
3687 const arg = sema.resolveInst(arg_ref);3707 const arg = sema.resolveInst(arg_ref);
3688 const arg_ty = sema.typeOf(arg);3708 const arg_ty = sema.typeOf(arg);
3689 if (try sema.resolveMaybeUndefVal(block, src, arg)) |val| {3709 if (try sema.resolveMaybeUndefVal(block, src, arg)) |val| {
3690 try writer.print("@as({}, {})", .{ arg_ty, val.fmtValue(arg_ty) });3710 try writer.print("@as({}, {})", .{
3711 arg_ty.fmt(target), val.fmtValue(arg_ty, target),
3712 });
3691 } else {3713 } else {
3692 try writer.print("@as({}, [runtime value])", .{arg_ty});3714 try writer.print("@as({}, [runtime value])", .{arg_ty.fmt(target)});
3693 }3715 }
3694 }3716 }
3695 try writer.print("\n", .{});3717 try writer.print("\n", .{});
...@@ -3982,9 +4004,10 @@ fn analyzeBlockBody(...@@ -3982,9 +4004,10 @@ fn analyzeBlockBody(
39824004
3983 const type_src = src; // TODO: better source location4005 const type_src = src; // TODO: better source location
3984 const valid_rt = try sema.validateRunTimeType(child_block, type_src, resolved_ty, false);4006 const valid_rt = try sema.validateRunTimeType(child_block, type_src, resolved_ty, false);
4007 const target = sema.mod.getTarget();
3985 if (!valid_rt) {4008 if (!valid_rt) {
3986 const msg = msg: {4009 const msg = msg: {
3987 const msg = try sema.errMsg(child_block, type_src, "value with comptime only type '{}' depends on runtime control flow", .{resolved_ty});4010 const msg = try sema.errMsg(child_block, type_src, "value with comptime only type '{}' depends on runtime control flow", .{resolved_ty.fmt(target)});
3988 errdefer msg.destroy(sema.gpa);4011 errdefer msg.destroy(sema.gpa);
39894012
3990 const runtime_src = child_block.runtime_cond orelse child_block.runtime_loop.?;4013 const runtime_src = child_block.runtime_cond orelse child_block.runtime_loop.?;
...@@ -4012,7 +4035,7 @@ fn analyzeBlockBody(...@@ -4012,7 +4035,7 @@ fn analyzeBlockBody(
4012 const br_operand = sema.air_instructions.items(.data)[br].br.operand;4035 const br_operand = sema.air_instructions.items(.data)[br].br.operand;
4013 const br_operand_src = src;4036 const br_operand_src = src;
4014 const br_operand_ty = sema.typeOf(br_operand);4037 const br_operand_ty = sema.typeOf(br_operand);
4015 if (br_operand_ty.eql(resolved_ty)) {4038 if (br_operand_ty.eql(resolved_ty, target)) {
4016 // No type coercion needed.4039 // No type coercion needed.
4017 continue;4040 continue;
4018 }4041 }
...@@ -4102,12 +4125,15 @@ pub fn analyzeExport(...@@ -4102,12 +4125,15 @@ pub fn analyzeExport(
4102) !void {4125) !void {
4103 const Export = Module.Export;4126 const Export = Module.Export;
4104 const mod = sema.mod;4127 const mod = sema.mod;
4128 const target = mod.getTarget();
41054129
4106 try mod.ensureDeclAnalyzed(exported_decl);4130 try mod.ensureDeclAnalyzed(exported_decl);
4107 // TODO run the same checks as we do for C ABI struct fields4131 // TODO run the same checks as we do for C ABI struct fields
4108 switch (exported_decl.ty.zigTypeTag()) {4132 switch (exported_decl.ty.zigTypeTag()) {
4109 .Fn, .Int, .Enum, .Struct, .Union, .Array, .Float => {},4133 .Fn, .Int, .Enum, .Struct, .Union, .Array, .Float => {},
4110 else => return sema.fail(block, src, "unable to export type '{}'", .{exported_decl.ty}),4134 else => return sema.fail(block, src, "unable to export type '{}'", .{
4135 exported_decl.ty.fmt(target),
4136 }),
4111 }4137 }
41124138
4113 const gpa = mod.gpa;4139 const gpa = mod.gpa;
...@@ -4520,6 +4546,7 @@ const GenericCallAdapter = struct {...@@ -4520,6 +4546,7 @@ const GenericCallAdapter = struct {
4520 precomputed_hash: u64,4546 precomputed_hash: u64,
4521 func_ty_info: Type.Payload.Function.Data,4547 func_ty_info: Type.Payload.Function.Data,
4522 comptime_tvs: []const TypedValue,4548 comptime_tvs: []const TypedValue,
4549 target: std.Target,
45234550
4524 pub fn eql(ctx: @This(), adapted_key: void, other_key: *Module.Fn) bool {4551 pub fn eql(ctx: @This(), adapted_key: void, other_key: *Module.Fn) bool {
4525 _ = adapted_key;4552 _ = adapted_key;
...@@ -4532,7 +4559,7 @@ const GenericCallAdapter = struct {...@@ -4532,7 +4559,7 @@ const GenericCallAdapter = struct {
4532 for (other_comptime_args[0..ctx.func_ty_info.param_types.len]) |other_arg, i| {4559 for (other_comptime_args[0..ctx.func_ty_info.param_types.len]) |other_arg, i| {
4533 if (other_arg.ty.tag() != .generic_poison) {4560 if (other_arg.ty.tag() != .generic_poison) {
4534 // anytype parameter4561 // anytype parameter
4535 if (!other_arg.ty.eql(ctx.comptime_tvs[i].ty)) {4562 if (!other_arg.ty.eql(ctx.comptime_tvs[i].ty, ctx.target)) {
4536 return false;4563 return false;
4537 }4564 }
4538 }4565 }
...@@ -4543,7 +4570,7 @@ const GenericCallAdapter = struct {...@@ -4543,7 +4570,7 @@ const GenericCallAdapter = struct {
4543 // but the callsite does not.4570 // but the callsite does not.
4544 return false;4571 return false;
4545 }4572 }
4546 if (!other_arg.val.eql(ctx.comptime_tvs[i].val, other_arg.ty)) {4573 if (!other_arg.val.eql(ctx.comptime_tvs[i].val, other_arg.ty, ctx.target)) {
4547 return false;4574 return false;
4548 }4575 }
4549 }4576 }
...@@ -4588,6 +4615,7 @@ fn analyzeCall(...@@ -4588,6 +4615,7 @@ fn analyzeCall(
4588 const mod = sema.mod;4615 const mod = sema.mod;
45894616
4590 const callee_ty = sema.typeOf(func);4617 const callee_ty = sema.typeOf(func);
4618 const target = sema.mod.getTarget();
4591 const func_ty = func_ty: {4619 const func_ty = func_ty: {
4592 switch (callee_ty.zigTypeTag()) {4620 switch (callee_ty.zigTypeTag()) {
4593 .Fn => break :func_ty callee_ty,4621 .Fn => break :func_ty callee_ty,
...@@ -4599,7 +4627,7 @@ fn analyzeCall(...@@ -4599,7 +4627,7 @@ fn analyzeCall(
4599 },4627 },
4600 else => {},4628 else => {},
4601 }4629 }
4602 return sema.fail(block, func_src, "type '{}' not a function", .{callee_ty});4630 return sema.fail(block, func_src, "type '{}' not a function", .{callee_ty.fmt(target)});
4603 };4631 };
46044632
4605 const func_ty_info = func_ty.fnInfo();4633 const func_ty_info = func_ty.fnInfo();
...@@ -4873,7 +4901,7 @@ fn analyzeCall(...@@ -4873,7 +4901,7 @@ fn analyzeCall(
4873 // bug generating invalid LLVM IR.4901 // bug generating invalid LLVM IR.
4874 const res2: Air.Inst.Ref = res2: {4902 const res2: Air.Inst.Ref = res2: {
4875 if (should_memoize and is_comptime_call) {4903 if (should_memoize and is_comptime_call) {
4876 if (mod.memoized_calls.get(memoized_call_key)) |result| {4904 if (mod.memoized_calls.getContext(memoized_call_key, .{ .target = target })) |result| {
4877 const ty_inst = try sema.addType(fn_ret_ty);4905 const ty_inst = try sema.addType(fn_ret_ty);
4878 try sema.air_values.append(gpa, result.val);4906 try sema.air_values.append(gpa, result.val);
4879 sema.air_instructions.set(block_inst, .{4907 sema.air_instructions.set(block_inst, .{
...@@ -4945,10 +4973,10 @@ fn analyzeCall(...@@ -4945,10 +4973,10 @@ fn analyzeCall(
4945 arg.* = try arg.*.copy(arena);4973 arg.* = try arg.*.copy(arena);
4946 }4974 }
49474975
4948 try mod.memoized_calls.put(gpa, memoized_call_key, .{4976 try mod.memoized_calls.putContext(gpa, memoized_call_key, .{
4949 .val = try result_val.copy(arena),4977 .val = try result_val.copy(arena),
4950 .arena = arena_allocator.state,4978 .arena = arena_allocator.state,
4951 });4979 }, .{ .target = sema.mod.getTarget() });
4952 delete_memoized_call_key = false;4980 delete_memoized_call_key = false;
4953 }4981 }
4954 }4982 }
...@@ -5037,6 +5065,7 @@ fn instantiateGenericCall(...@@ -5037,6 +5065,7 @@ fn instantiateGenericCall(
5037 std.hash.autoHash(&hasher, @ptrToInt(module_fn));5065 std.hash.autoHash(&hasher, @ptrToInt(module_fn));
50385066
5039 const comptime_tvs = try sema.arena.alloc(TypedValue, func_ty_info.param_types.len);5067 const comptime_tvs = try sema.arena.alloc(TypedValue, func_ty_info.param_types.len);
5068 const target = sema.mod.getTarget();
50405069
5041 for (func_ty_info.param_types) |param_ty, i| {5070 for (func_ty_info.param_types) |param_ty, i| {
5042 const is_comptime = func_ty_info.paramIsComptime(i);5071 const is_comptime = func_ty_info.paramIsComptime(i);
...@@ -5045,7 +5074,7 @@ fn instantiateGenericCall(...@@ -5045,7 +5074,7 @@ fn instantiateGenericCall(
5045 const casted_arg = try sema.coerce(block, param_ty, uncasted_args[i], arg_src);5074 const casted_arg = try sema.coerce(block, param_ty, uncasted_args[i], arg_src);
5046 if (try sema.resolveMaybeUndefVal(block, arg_src, casted_arg)) |arg_val| {5075 if (try sema.resolveMaybeUndefVal(block, arg_src, casted_arg)) |arg_val| {
5047 if (param_ty.tag() != .generic_poison) {5076 if (param_ty.tag() != .generic_poison) {
5048 arg_val.hash(param_ty, &hasher);5077 arg_val.hash(param_ty, &hasher, target);
5049 }5078 }
5050 comptime_tvs[i] = .{5079 comptime_tvs[i] = .{
5051 // This will be different than `param_ty` in the case of `generic_poison`.5080 // This will be different than `param_ty` in the case of `generic_poison`.
...@@ -5070,8 +5099,9 @@ fn instantiateGenericCall(...@@ -5070,8 +5099,9 @@ fn instantiateGenericCall(
5070 .precomputed_hash = precomputed_hash,5099 .precomputed_hash = precomputed_hash,
5071 .func_ty_info = func_ty_info,5100 .func_ty_info = func_ty_info,
5072 .comptime_tvs = comptime_tvs,5101 .comptime_tvs = comptime_tvs,
5102 .target = target,
5073 };5103 };
5074 const gop = try mod.monomorphed_funcs.getOrPutAdapted(gpa, {}, adapter);5104 const gop = try mod.monomorphed_funcs.getOrPutContextAdapted(gpa, {}, adapter, .{ .target = target });
5075 if (!gop.found_existing) {5105 if (!gop.found_existing) {
5076 const new_module_func = try gpa.create(Module.Fn);5106 const new_module_func = try gpa.create(Module.Fn);
5077 gop.key_ptr.* = new_module_func;5107 gop.key_ptr.* = new_module_func;
...@@ -5255,7 +5285,7 @@ fn instantiateGenericCall(...@@ -5255,7 +5285,7 @@ fn instantiateGenericCall(
5255 new_decl.analysis = .complete;5285 new_decl.analysis = .complete;
52565286
5257 log.debug("generic function '{s}' instantiated with type {}", .{5287 log.debug("generic function '{s}' instantiated with type {}", .{
5258 new_decl.name, new_decl.ty,5288 new_decl.name, new_decl.ty.fmtDebug(),
5259 });5289 });
52605290
5261 // Queue up a `codegen_func` work item for the new Fn. The `comptime_args` field5291 // Queue up a `codegen_func` work item for the new Fn. The `comptime_args` field
...@@ -5410,7 +5440,8 @@ fn zirArrayType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -5410,7 +5440,8 @@ fn zirArrayType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
5410 const bin_inst = sema.code.instructions.items(.data)[inst].bin;5440 const bin_inst = sema.code.instructions.items(.data)[inst].bin;
5411 const len = try sema.resolveInt(block, .unneeded, bin_inst.lhs, Type.usize);5441 const len = try sema.resolveInt(block, .unneeded, bin_inst.lhs, Type.usize);
5412 const elem_type = try sema.resolveType(block, .unneeded, bin_inst.rhs);5442 const elem_type = try sema.resolveType(block, .unneeded, bin_inst.rhs);
5413 const array_ty = try Type.array(sema.arena, len, null, elem_type);5443 const target = sema.mod.getTarget();
5444 const array_ty = try Type.array(sema.arena, len, null, elem_type, target);
54145445
5415 return sema.addType(array_ty);5446 return sema.addType(array_ty);
5416}5447}
...@@ -5429,7 +5460,8 @@ fn zirArrayTypeSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil...@@ -5429,7 +5460,8 @@ fn zirArrayTypeSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil
5429 const uncasted_sentinel = sema.resolveInst(extra.sentinel);5460 const uncasted_sentinel = sema.resolveInst(extra.sentinel);
5430 const sentinel = try sema.coerce(block, elem_type, uncasted_sentinel, sentinel_src);5461 const sentinel = try sema.coerce(block, elem_type, uncasted_sentinel, sentinel_src);
5431 const sentinel_val = try sema.resolveConstValue(block, sentinel_src, sentinel);5462 const sentinel_val = try sema.resolveConstValue(block, sentinel_src, sentinel);
5432 const array_ty = try Type.array(sema.arena, len, sentinel_val, elem_type);5463 const target = sema.mod.getTarget();
5464 const array_ty = try Type.array(sema.arena, len, sentinel_val, elem_type, target);
54335465
5434 return sema.addType(array_ty);5466 return sema.addType(array_ty);
5435}5467}
...@@ -5456,13 +5488,14 @@ fn zirErrorUnionType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -5456,13 +5488,14 @@ fn zirErrorUnionType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
5456 const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };5488 const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };
5457 const error_set = try sema.resolveType(block, lhs_src, extra.lhs);5489 const error_set = try sema.resolveType(block, lhs_src, extra.lhs);
5458 const payload = try sema.resolveType(block, rhs_src, extra.rhs);5490 const payload = try sema.resolveType(block, rhs_src, extra.rhs);
5491 const target = sema.mod.getTarget();
54595492
5460 if (error_set.zigTypeTag() != .ErrorSet) {5493 if (error_set.zigTypeTag() != .ErrorSet) {
5461 return sema.fail(block, lhs_src, "expected error set type, found {}", .{5494 return sema.fail(block, lhs_src, "expected error set type, found {}", .{
5462 error_set,5495 error_set.fmt(target),
5463 });5496 });
5464 }5497 }
5465 const err_union_ty = try Module.errorUnionType(sema.arena, error_set, payload);5498 const err_union_ty = try Type.errorUnion(sema.arena, error_set, payload, target);
5466 return sema.addType(err_union_ty);5499 return sema.addType(err_union_ty);
5467}5500}
54685501
...@@ -5520,9 +5553,10 @@ fn zirIntToError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -5520,9 +5553,10 @@ fn zirIntToError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
5520 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };5553 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
55215554
5522 const op = sema.resolveInst(inst_data.operand);5555 const op = sema.resolveInst(inst_data.operand);
5556 const target = sema.mod.getTarget();
55235557
5524 if (try sema.resolveDefinedValue(block, operand_src, op)) |value| {5558 if (try sema.resolveDefinedValue(block, operand_src, op)) |value| {
5525 const int = value.toUnsignedInt();5559 const int = value.toUnsignedInt(target);
5526 if (int > sema.mod.global_error_set.count() or int == 0)5560 if (int > sema.mod.global_error_set.count() or int == 0)
5527 return sema.fail(block, operand_src, "integer value {d} represents no error", .{int});5561 return sema.fail(block, operand_src, "integer value {d} represents no error", .{int});
5528 const payload = try sema.arena.create(Value.Payload.Error);5562 const payload = try sema.arena.create(Value.Payload.Error);
...@@ -5569,10 +5603,11 @@ fn zirMergeErrorSets(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -5569,10 +5603,11 @@ fn zirMergeErrorSets(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
5569 }5603 }
5570 const lhs_ty = try sema.analyzeAsType(block, lhs_src, lhs);5604 const lhs_ty = try sema.analyzeAsType(block, lhs_src, lhs);
5571 const rhs_ty = try sema.analyzeAsType(block, rhs_src, rhs);5605 const rhs_ty = try sema.analyzeAsType(block, rhs_src, rhs);
5606 const target = sema.mod.getTarget();
5572 if (lhs_ty.zigTypeTag() != .ErrorSet)5607 if (lhs_ty.zigTypeTag() != .ErrorSet)
5573 return sema.fail(block, lhs_src, "expected error set type, found {}", .{lhs_ty});5608 return sema.fail(block, lhs_src, "expected error set type, found {}", .{lhs_ty.fmt(target)});
5574 if (rhs_ty.zigTypeTag() != .ErrorSet)5609 if (rhs_ty.zigTypeTag() != .ErrorSet)
5575 return sema.fail(block, rhs_src, "expected error set type, found {}", .{rhs_ty});5610 return sema.fail(block, rhs_src, "expected error set type, found {}", .{rhs_ty.fmt(target)});
55765611
5577 // Anything merged with anyerror is anyerror.5612 // Anything merged with anyerror is anyerror.
5578 if (lhs_ty.tag() == .anyerror or rhs_ty.tag() == .anyerror) {5613 if (lhs_ty.tag() == .anyerror or rhs_ty.tag() == .anyerror) {
...@@ -5618,6 +5653,7 @@ fn zirEnumToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -5618,6 +5653,7 @@ fn zirEnumToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
5618 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };5653 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
5619 const operand = sema.resolveInst(inst_data.operand);5654 const operand = sema.resolveInst(inst_data.operand);
5620 const operand_ty = sema.typeOf(operand);5655 const operand_ty = sema.typeOf(operand);
5656 const target = sema.mod.getTarget();
56215657
5622 const enum_tag: Air.Inst.Ref = switch (operand_ty.zigTypeTag()) {5658 const enum_tag: Air.Inst.Ref = switch (operand_ty.zigTypeTag()) {
5623 .Enum => operand,5659 .Enum => operand,
...@@ -5634,7 +5670,7 @@ fn zirEnumToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -5634,7 +5670,7 @@ fn zirEnumToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
5634 },5670 },
5635 else => {5671 else => {
5636 return sema.fail(block, operand_src, "expected enum or tagged union, found {}", .{5672 return sema.fail(block, operand_src, "expected enum or tagged union, found {}", .{
5637 operand_ty,5673 operand_ty.fmt(target),
5638 });5674 });
5639 },5675 },
5640 };5676 };
...@@ -5668,7 +5704,7 @@ fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -5668,7 +5704,7 @@ fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
5668 const operand = sema.resolveInst(extra.rhs);5704 const operand = sema.resolveInst(extra.rhs);
56695705
5670 if (dest_ty.zigTypeTag() != .Enum) {5706 if (dest_ty.zigTypeTag() != .Enum) {
5671 return sema.fail(block, dest_ty_src, "expected enum, found {}", .{dest_ty});5707 return sema.fail(block, dest_ty_src, "expected enum, found {}", .{dest_ty.fmt(target)});
5672 }5708 }
56735709
5674 if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |int_val| {5710 if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |int_val| {
...@@ -5684,7 +5720,7 @@ fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -5684,7 +5720,7 @@ fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
5684 block,5720 block,
5685 src,5721 src,
5686 "enum '{}' has no tag with value {}",5722 "enum '{}' has no tag with value {}",
5687 .{ dest_ty, int_val.fmtValue(sema.typeOf(operand)) },5723 .{ dest_ty.fmt(target), int_val.fmtValue(sema.typeOf(operand), target) },
5688 );5724 );
5689 errdefer msg.destroy(sema.gpa);5725 errdefer msg.destroy(sema.gpa);
5690 try sema.mod.errNoteNonLazy(5726 try sema.mod.errNoteNonLazy(
...@@ -5733,13 +5769,13 @@ fn analyzeOptionalPayloadPtr(...@@ -5733,13 +5769,13 @@ fn analyzeOptionalPayloadPtr(
5733 const optional_ptr_ty = sema.typeOf(optional_ptr);5769 const optional_ptr_ty = sema.typeOf(optional_ptr);
5734 assert(optional_ptr_ty.zigTypeTag() == .Pointer);5770 assert(optional_ptr_ty.zigTypeTag() == .Pointer);
57355771
5772 const target = sema.mod.getTarget();
5736 const opt_type = optional_ptr_ty.elemType();5773 const opt_type = optional_ptr_ty.elemType();
5737 if (opt_type.zigTypeTag() != .Optional) {5774 if (opt_type.zigTypeTag() != .Optional) {
5738 return sema.fail(block, src, "expected optional type, found {}", .{opt_type});5775 return sema.fail(block, src, "expected optional type, found {}", .{opt_type.fmt(target)});
5739 }5776 }
57405777
5741 const child_type = try opt_type.optionalChildAlloc(sema.arena);5778 const child_type = try opt_type.optionalChildAlloc(sema.arena);
5742 const target = sema.mod.getTarget();
5743 const child_pointer = try Type.ptr(sema.arena, target, .{5779 const child_pointer = try Type.ptr(sema.arena, target, .{
5744 .pointee_type = child_type,5780 .pointee_type = child_type,
5745 .mutable = !optional_ptr_ty.isConstPtr(),5781 .mutable = !optional_ptr_ty.isConstPtr(),
...@@ -5858,8 +5894,12 @@ fn zirErrUnionPayload(...@@ -5858,8 +5894,12 @@ fn zirErrUnionPayload(
5858 const operand = sema.resolveInst(inst_data.operand);5894 const operand = sema.resolveInst(inst_data.operand);
5859 const operand_src = src;5895 const operand_src = src;
5860 const operand_ty = sema.typeOf(operand);5896 const operand_ty = sema.typeOf(operand);
5861 if (operand_ty.zigTypeTag() != .ErrorUnion)5897 if (operand_ty.zigTypeTag() != .ErrorUnion) {
5862 return sema.fail(block, operand_src, "expected error union type, found '{}'", .{operand_ty});5898 const target = sema.mod.getTarget();
5899 return sema.fail(block, operand_src, "expected error union type, found '{}'", .{
5900 operand_ty.fmt(target),
5901 });
5902 }
58635903
5864 if (try sema.resolveDefinedValue(block, src, operand)) |val| {5904 if (try sema.resolveDefinedValue(block, src, operand)) |val| {
5865 if (val.getError()) |name| {5905 if (val.getError()) |name| {
...@@ -5906,11 +5946,14 @@ fn analyzeErrUnionPayloadPtr(...@@ -5906,11 +5946,14 @@ fn analyzeErrUnionPayloadPtr(
5906 const operand_ty = sema.typeOf(operand);5946 const operand_ty = sema.typeOf(operand);
5907 assert(operand_ty.zigTypeTag() == .Pointer);5947 assert(operand_ty.zigTypeTag() == .Pointer);
59085948
5909 if (operand_ty.elemType().zigTypeTag() != .ErrorUnion)5949 const target = sema.mod.getTarget();
5910 return sema.fail(block, src, "expected error union type, found {}", .{operand_ty.elemType()});5950 if (operand_ty.elemType().zigTypeTag() != .ErrorUnion) {
5951 return sema.fail(block, src, "expected error union type, found {}", .{
5952 operand_ty.elemType().fmt(target),
5953 });
5954 }
59115955
5912 const payload_ty = operand_ty.elemType().errorUnionPayload();5956 const payload_ty = operand_ty.elemType().errorUnionPayload();
5913 const target = sema.mod.getTarget();
5914 const operand_pointer_ty = try Type.ptr(sema.arena, target, .{5957 const operand_pointer_ty = try Type.ptr(sema.arena, target, .{
5915 .pointee_type = payload_ty,5958 .pointee_type = payload_ty,
5916 .mutable = !operand_ty.isConstPtr(),5959 .mutable = !operand_ty.isConstPtr(),
...@@ -5970,8 +6013,12 @@ fn zirErrUnionCode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -5970,8 +6013,12 @@ fn zirErrUnionCode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
5970 const src = inst_data.src();6013 const src = inst_data.src();
5971 const operand = sema.resolveInst(inst_data.operand);6014 const operand = sema.resolveInst(inst_data.operand);
5972 const operand_ty = sema.typeOf(operand);6015 const operand_ty = sema.typeOf(operand);
5973 if (operand_ty.zigTypeTag() != .ErrorUnion)6016 const target = sema.mod.getTarget();
5974 return sema.fail(block, src, "expected error union type, found '{}'", .{operand_ty});6017 if (operand_ty.zigTypeTag() != .ErrorUnion) {
6018 return sema.fail(block, src, "expected error union type, found '{}'", .{
6019 operand_ty.fmt(target),
6020 });
6021 }
59756022
5976 const result_ty = operand_ty.errorUnionSet();6023 const result_ty = operand_ty.errorUnionSet();
59776024
...@@ -5995,8 +6042,12 @@ fn zirErrUnionCodePtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE...@@ -5995,8 +6042,12 @@ fn zirErrUnionCodePtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
5995 const operand_ty = sema.typeOf(operand);6042 const operand_ty = sema.typeOf(operand);
5996 assert(operand_ty.zigTypeTag() == .Pointer);6043 assert(operand_ty.zigTypeTag() == .Pointer);
59976044
5998 if (operand_ty.elemType().zigTypeTag() != .ErrorUnion)6045 if (operand_ty.elemType().zigTypeTag() != .ErrorUnion) {
5999 return sema.fail(block, src, "expected error union type, found {}", .{operand_ty.elemType()});6046 const target = sema.mod.getTarget();
6047 return sema.fail(block, src, "expected error union type, found {}", .{
6048 operand_ty.elemType().fmt(target),
6049 });
6050 }
60006051
6001 const result_ty = operand_ty.elemType().errorUnionSet();6052 const result_ty = operand_ty.elemType().errorUnionSet();
60026053
...@@ -6019,8 +6070,12 @@ fn zirEnsureErrPayloadVoid(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com...@@ -6019,8 +6070,12 @@ fn zirEnsureErrPayloadVoid(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
6019 const src = inst_data.src();6070 const src = inst_data.src();
6020 const operand = sema.resolveInst(inst_data.operand);6071 const operand = sema.resolveInst(inst_data.operand);
6021 const operand_ty = sema.typeOf(operand);6072 const operand_ty = sema.typeOf(operand);
6022 if (operand_ty.zigTypeTag() != .ErrorUnion)6073 const target = sema.mod.getTarget();
6023 return sema.fail(block, src, "expected error union type, found '{}'", .{operand_ty});6074 if (operand_ty.zigTypeTag() != .ErrorUnion) {
6075 return sema.fail(block, src, "expected error union type, found '{}'", .{
6076 operand_ty.fmt(target),
6077 });
6078 }
6024 if (operand_ty.errorUnionPayload().zigTypeTag() != .Void) {6079 if (operand_ty.errorUnionPayload().zigTypeTag() != .Void) {
6025 return sema.fail(block, src, "expression value is ignored", .{});6080 return sema.fail(block, src, "expression value is ignored", .{});
6026 }6081 }
...@@ -6205,7 +6260,7 @@ fn funcCommon(...@@ -6205,7 +6260,7 @@ fn funcCommon(
62056260
6206 const fn_ty: Type = fn_ty: {6261 const fn_ty: Type = fn_ty: {
6207 const alignment: u32 = if (align_val.tag() == .null_value) 0 else a: {6262 const alignment: u32 = if (align_val.tag() == .null_value) 0 else a: {
6208 const alignment = @intCast(u32, align_val.toUnsignedInt());6263 const alignment = @intCast(u32, align_val.toUnsignedInt(target));
6209 if (alignment == target_util.defaultFunctionAlignment(target)) {6264 if (alignment == target_util.defaultFunctionAlignment(target)) {
6210 break :a 0;6265 break :a 0;
6211 } else {6266 } else {
...@@ -6494,7 +6549,8 @@ fn zirPtrToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -6494,7 +6549,8 @@ fn zirPtrToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
6494 const ptr = sema.resolveInst(inst_data.operand);6549 const ptr = sema.resolveInst(inst_data.operand);
6495 const ptr_ty = sema.typeOf(ptr);6550 const ptr_ty = sema.typeOf(ptr);
6496 if (!ptr_ty.isPtrAtRuntime()) {6551 if (!ptr_ty.isPtrAtRuntime()) {
6497 return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ty});6552 const target = sema.mod.getTarget();
6553 return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ty.fmt(target)});
6498 }6554 }
6499 if (try sema.resolveMaybeUndefVal(block, ptr_src, ptr)) |ptr_val| {6555 if (try sema.resolveMaybeUndefVal(block, ptr_src, ptr)) |ptr_val| {
6500 return sema.addConstant(Type.usize, ptr_val);6556 return sema.addConstant(Type.usize, ptr_val);
...@@ -6652,6 +6708,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -6652,6 +6708,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
6652 const dest_ty = try sema.resolveType(block, dest_ty_src, extra.lhs);6708 const dest_ty = try sema.resolveType(block, dest_ty_src, extra.lhs);
6653 const operand = sema.resolveInst(extra.rhs);6709 const operand = sema.resolveInst(extra.rhs);
66546710
6711 const target = sema.mod.getTarget();
6655 const dest_is_comptime_float = switch (dest_ty.zigTypeTag()) {6712 const dest_is_comptime_float = switch (dest_ty.zigTypeTag()) {
6656 .ComptimeFloat => true,6713 .ComptimeFloat => true,
6657 .Float => false,6714 .Float => false,
...@@ -6659,7 +6716,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -6659,7 +6716,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
6659 block,6716 block,
6660 dest_ty_src,6717 dest_ty_src,
6661 "expected float type, found '{}'",6718 "expected float type, found '{}'",
6662 .{dest_ty},6719 .{dest_ty.fmt(target)},
6663 ),6720 ),
6664 };6721 };
66656722
...@@ -6670,7 +6727,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -6670,7 +6727,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
6670 block,6727 block,
6671 operand_src,6728 operand_src,
6672 "expected float type, found '{}'",6729 "expected float type, found '{}'",
6673 .{operand_ty},6730 .{operand_ty.fmt(target)},
6674 ),6731 ),
6675 }6732 }
66766733
...@@ -6680,7 +6737,6 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -6680,7 +6737,6 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
6680 if (dest_is_comptime_float) {6737 if (dest_is_comptime_float) {
6681 return sema.fail(block, src, "unable to cast runtime value to 'comptime_float'", .{});6738 return sema.fail(block, src, "unable to cast runtime value to 'comptime_float'", .{});
6682 }6739 }
6683 const target = sema.mod.getTarget();
6684 const src_bits = operand_ty.floatBits(target);6740 const src_bits = operand_ty.floatBits(target);
6685 const dst_bits = dest_ty.floatBits(target);6741 const dst_bits = dest_ty.floatBits(target);
6686 if (dst_bits >= src_bits) {6742 if (dst_bits >= src_bits) {
...@@ -6839,13 +6895,14 @@ fn zirSwitchCapture(...@@ -6839,13 +6895,14 @@ fn zirSwitchCapture(
6839 const item = sema.resolveInst(scalar_prong.item);6895 const item = sema.resolveInst(scalar_prong.item);
6840 // Previous switch validation ensured this will succeed6896 // Previous switch validation ensured this will succeed
6841 const item_val = sema.resolveConstValue(block, .unneeded, item) catch unreachable;6897 const item_val = sema.resolveConstValue(block, .unneeded, item) catch unreachable;
6898 const target = sema.mod.getTarget();
68426899
6843 switch (operand_ty.zigTypeTag()) {6900 switch (operand_ty.zigTypeTag()) {
6844 .Union => {6901 .Union => {
6845 const union_obj = operand_ty.cast(Type.Payload.Union).?.data;6902 const union_obj = operand_ty.cast(Type.Payload.Union).?.data;
6846 const enum_ty = union_obj.tag_ty;6903 const enum_ty = union_obj.tag_ty;
68476904
6848 const field_index_usize = enum_ty.enumTagFieldIndex(item_val).?;6905 const field_index_usize = enum_ty.enumTagFieldIndex(item_val, target).?;
6849 const field_index = @intCast(u32, field_index_usize);6906 const field_index = @intCast(u32, field_index_usize);
6850 const field = union_obj.fields.values()[field_index];6907 const field = union_obj.fields.values()[field_index];
68516908
...@@ -6854,7 +6911,6 @@ fn zirSwitchCapture(...@@ -6854,7 +6911,6 @@ fn zirSwitchCapture(
6854 if (is_ref) {6911 if (is_ref) {
6855 assert(operand_is_ref);6912 assert(operand_is_ref);
68566913
6857 const target = sema.mod.getTarget();
6858 const field_ty_ptr = try Type.ptr(sema.arena, target, .{6914 const field_ty_ptr = try Type.ptr(sema.arena, target, .{
6859 .pointee_type = field.ty,6915 .pointee_type = field.ty,
6860 .@"addrspace" = .generic,6916 .@"addrspace" = .generic,
...@@ -6894,7 +6950,7 @@ fn zirSwitchCapture(...@@ -6894,7 +6950,7 @@ fn zirSwitchCapture(
6894 },6950 },
6895 else => {6951 else => {
6896 return sema.fail(block, operand_src, "switch on type '{}' provides no capture value", .{6952 return sema.fail(block, operand_src, "switch on type '{}' provides no capture value", .{
6897 operand_ty,6953 operand_ty.fmt(target),
6898 });6954 });
6899 },6955 },
6900 }6956 }
...@@ -6915,6 +6971,7 @@ fn zirSwitchCond(...@@ -6915,6 +6971,7 @@ fn zirSwitchCond(
6915 else6971 else
6916 operand_ptr;6972 operand_ptr;
6917 const operand_ty = sema.typeOf(operand);6973 const operand_ty = sema.typeOf(operand);
6974 const target = sema.mod.getTarget();
69186975
6919 switch (operand_ty.zigTypeTag()) {6976 switch (operand_ty.zigTypeTag()) {
6920 .Type,6977 .Type,
...@@ -6962,7 +7019,7 @@ fn zirSwitchCond(...@@ -6962,7 +7019,7 @@ fn zirSwitchCond(
6962 .Vector,7019 .Vector,
6963 .Frame,7020 .Frame,
6964 .AnyFrame,7021 .AnyFrame,
6965 => return sema.fail(block, src, "switch on type '{}'", .{operand_ty}),7022 => return sema.fail(block, src, "switch on type '{}'", .{operand_ty.fmt(target)}),
6966 }7023 }
6967}7024}
69687025
...@@ -7030,6 +7087,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -7030,6 +7087,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
7030 return sema.failWithOwnedErrorMsg(block, msg);7087 return sema.failWithOwnedErrorMsg(block, msg);
7031 }7088 }
70327089
7090 const target = sema.mod.getTarget();
7091
7033 // Validate for duplicate items, missing else prong, and invalid range.7092 // Validate for duplicate items, missing else prong, and invalid range.
7034 switch (operand_ty.zigTypeTag()) {7093 switch (operand_ty.zigTypeTag()) {
7035 .Enum => {7094 .Enum => {
...@@ -7115,7 +7174,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -7115,7 +7174,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
7115 operand_ty.declSrcLoc(),7174 operand_ty.declSrcLoc(),
7116 msg,7175 msg,
7117 "enum '{}' declared here",7176 "enum '{}' declared here",
7118 .{operand_ty},7177 .{operand_ty.fmt(target)},
7119 );7178 );
7120 break :msg msg;7179 break :msg msg;
7121 };7180 };
...@@ -7232,7 +7291,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -7232,7 +7291,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
7232 operand_ty.declSrcLoc(),7291 operand_ty.declSrcLoc(),
7233 msg,7292 msg,
7234 "error set '{}' declared here",7293 "error set '{}' declared here",
7235 .{operand_ty},7294 .{operand_ty.fmt(target)},
7236 );7295 );
7237 return sema.failWithOwnedErrorMsg(block, msg);7296 return sema.failWithOwnedErrorMsg(block, msg);
7238 }7297 }
...@@ -7260,7 +7319,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -7260,7 +7319,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
7260 },7319 },
7261 .Union => return sema.fail(block, src, "TODO validate switch .Union", .{}),7320 .Union => return sema.fail(block, src, "TODO validate switch .Union", .{}),
7262 .Int, .ComptimeInt => {7321 .Int, .ComptimeInt => {
7263 var range_set = RangeSet.init(gpa);7322 var range_set = RangeSet.init(gpa, target);
7264 defer range_set.deinit();7323 defer range_set.deinit();
72657324
7266 var extra_index: usize = special.end;7325 var extra_index: usize = special.end;
...@@ -7333,7 +7392,6 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -7333,7 +7392,6 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
7333 var arena = std.heap.ArenaAllocator.init(gpa);7392 var arena = std.heap.ArenaAllocator.init(gpa);
7334 defer arena.deinit();7393 defer arena.deinit();
73357394
7336 const target = sema.mod.getTarget();
7337 const min_int = try operand_ty.minInt(arena.allocator(), target);7395 const min_int = try operand_ty.minInt(arena.allocator(), target);
7338 const max_int = try operand_ty.maxInt(arena.allocator(), target);7396 const max_int = try operand_ty.maxInt(arena.allocator(), target);
7339 if (try range_set.spans(min_int, max_int, operand_ty)) {7397 if (try range_set.spans(min_int, max_int, operand_ty)) {
...@@ -7437,11 +7495,14 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -7437,11 +7495,14 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
7437 block,7495 block,
7438 src,7496 src,
7439 "else prong required when switching on type '{}'",7497 "else prong required when switching on type '{}'",
7440 .{operand_ty},7498 .{operand_ty.fmt(target)},
7441 );7499 );
7442 }7500 }
74437501
7444 var seen_values = ValueSrcMap.initContext(gpa, .{ .ty = operand_ty });7502 var seen_values = ValueSrcMap.initContext(gpa, .{
7503 .ty = operand_ty,
7504 .target = target,
7505 });
7445 defer seen_values.deinit();7506 defer seen_values.deinit();
74467507
7447 var extra_index: usize = special.end;7508 var extra_index: usize = special.end;
...@@ -7505,7 +7566,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -7505,7 +7566,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
7505 .ComptimeFloat,7566 .ComptimeFloat,
7506 .Float,7567 .Float,
7507 => return sema.fail(block, operand_src, "invalid switch operand type '{}'", .{7568 => return sema.fail(block, operand_src, "invalid switch operand type '{}'", .{
7508 operand_ty,7569 operand_ty.fmt(target),
7509 }),7570 }),
7510 }7571 }
75117572
...@@ -7555,7 +7616,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -7555,7 +7616,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
7555 const item = sema.resolveInst(item_ref);7616 const item = sema.resolveInst(item_ref);
7556 // Validation above ensured these will succeed.7617 // Validation above ensured these will succeed.
7557 const item_val = sema.resolveConstValue(&child_block, .unneeded, item) catch unreachable;7618 const item_val = sema.resolveConstValue(&child_block, .unneeded, item) catch unreachable;
7558 if (operand_val.eql(item_val, operand_ty)) {7619 if (operand_val.eql(item_val, operand_ty, target)) {
7559 return sema.resolveBlockBody(block, src, &child_block, body, inst, merges);7620 return sema.resolveBlockBody(block, src, &child_block, body, inst, merges);
7560 }7621 }
7561 }7622 }
...@@ -7577,7 +7638,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -7577,7 +7638,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
7577 const item = sema.resolveInst(item_ref);7638 const item = sema.resolveInst(item_ref);
7578 // Validation above ensured these will succeed.7639 // Validation above ensured these will succeed.
7579 const item_val = sema.resolveConstValue(&child_block, .unneeded, item) catch unreachable;7640 const item_val = sema.resolveConstValue(&child_block, .unneeded, item) catch unreachable;
7580 if (operand_val.eql(item_val, operand_ty)) {7641 if (operand_val.eql(item_val, operand_ty, target)) {
7581 return sema.resolveBlockBody(block, src, &child_block, body, inst, merges);7642 return sema.resolveBlockBody(block, src, &child_block, body, inst, merges);
7582 }7643 }
7583 }7644 }
...@@ -7592,8 +7653,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -7592,8 +7653,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
7592 // Validation above ensured these will succeed.7653 // Validation above ensured these will succeed.
7593 const first_tv = sema.resolveInstConst(&child_block, .unneeded, item_first) catch unreachable;7654 const first_tv = sema.resolveInstConst(&child_block, .unneeded, item_first) catch unreachable;
7594 const last_tv = sema.resolveInstConst(&child_block, .unneeded, item_last) catch unreachable;7655 const last_tv = sema.resolveInstConst(&child_block, .unneeded, item_last) catch unreachable;
7595 if (Value.compare(operand_val, .gte, first_tv.val, operand_ty) and7656 if (Value.compare(operand_val, .gte, first_tv.val, operand_ty, target) and
7596 Value.compare(operand_val, .lte, last_tv.val, operand_ty))7657 Value.compare(operand_val, .lte, last_tv.val, operand_ty, target))
7597 {7658 {
7598 return sema.resolveBlockBody(block, src, &child_block, body, inst, merges);7659 return sema.resolveBlockBody(block, src, &child_block, body, inst, merges);
7599 }7660 }
...@@ -7907,14 +7968,15 @@ fn validateSwitchItemEnum(...@@ -7907,14 +7968,15 @@ fn validateSwitchItemEnum(
7907 switch_prong_src: Module.SwitchProngSrc,7968 switch_prong_src: Module.SwitchProngSrc,
7908) CompileError!void {7969) CompileError!void {
7909 const item_tv = try sema.resolveSwitchItemVal(block, item_ref, src_node_offset, switch_prong_src, .none);7970 const item_tv = try sema.resolveSwitchItemVal(block, item_ref, src_node_offset, switch_prong_src, .none);
7910 const field_index = item_tv.ty.enumTagFieldIndex(item_tv.val) orelse {7971 const target = sema.mod.getTarget();
7972 const field_index = item_tv.ty.enumTagFieldIndex(item_tv.val, target) orelse {
7911 const msg = msg: {7973 const msg = msg: {
7912 const src = switch_prong_src.resolve(sema.gpa, block.src_decl, src_node_offset, .none);7974 const src = switch_prong_src.resolve(sema.gpa, block.src_decl, src_node_offset, .none);
7913 const msg = try sema.errMsg(7975 const msg = try sema.errMsg(
7914 block,7976 block,
7915 src,7977 src,
7916 "enum '{}' has no tag with value '{}'",7978 "enum '{}' has no tag with value '{}'",
7917 .{ item_tv.ty, item_tv.val.fmtValue(item_tv.ty) },7979 .{ item_tv.ty.fmt(target), item_tv.val.fmtValue(item_tv.ty, target) },
7918 );7980 );
7919 errdefer msg.destroy(sema.gpa);7981 errdefer msg.destroy(sema.gpa);
7920 try sema.mod.errNoteNonLazy(7982 try sema.mod.errNoteNonLazy(
...@@ -8030,12 +8092,13 @@ fn validateSwitchNoRange(...@@ -8030,12 +8092,13 @@ fn validateSwitchNoRange(
8030 const operand_src: LazySrcLoc = .{ .node_offset_switch_operand = src_node_offset };8092 const operand_src: LazySrcLoc = .{ .node_offset_switch_operand = src_node_offset };
8031 const range_src: LazySrcLoc = .{ .node_offset_switch_range = src_node_offset };8093 const range_src: LazySrcLoc = .{ .node_offset_switch_range = src_node_offset };
80328094
8095 const target = sema.mod.getTarget();
8033 const msg = msg: {8096 const msg = msg: {
8034 const msg = try sema.errMsg(8097 const msg = try sema.errMsg(
8035 block,8098 block,
8036 operand_src,8099 operand_src,
8037 "ranges not allowed when switching on type '{}'",8100 "ranges not allowed when switching on type '{}'",
8038 .{operand_ty},8101 .{operand_ty.fmt(target)},
8039 );8102 );
8040 errdefer msg.destroy(sema.gpa);8103 errdefer msg.destroy(sema.gpa);
8041 try sema.errNote(8104 try sema.errNote(
...@@ -8058,6 +8121,7 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -8058,6 +8121,7 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
8058 const unresolved_ty = try sema.resolveType(block, ty_src, extra.lhs);8121 const unresolved_ty = try sema.resolveType(block, ty_src, extra.lhs);
8059 const field_name = try sema.resolveConstString(block, name_src, extra.rhs);8122 const field_name = try sema.resolveConstString(block, name_src, extra.rhs);
8060 const ty = try sema.resolveTypeFields(block, ty_src, unresolved_ty);8123 const ty = try sema.resolveTypeFields(block, ty_src, unresolved_ty);
8124 const target = sema.mod.getTarget();
80618125
8062 const has_field = hf: {8126 const has_field = hf: {
8063 if (ty.isSlice()) {8127 if (ty.isSlice()) {
...@@ -8080,7 +8144,7 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -8080,7 +8144,7 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
8080 .Enum => ty.enumFields().contains(field_name),8144 .Enum => ty.enumFields().contains(field_name),
8081 .Array => mem.eql(u8, field_name, "len"),8145 .Array => mem.eql(u8, field_name, "len"),
8082 else => return sema.fail(block, ty_src, "type '{}' does not support '@hasField'", .{8146 else => return sema.fail(block, ty_src, "type '{}' does not support '@hasField'", .{
8083 ty,8147 ty.fmt(target),
8084 }),8148 }),
8085 };8149 };
8086 };8150 };
...@@ -8227,25 +8291,25 @@ fn zirShl(...@@ -8227,25 +8291,25 @@ fn zirShl(
82278291
8228 const val = switch (air_tag) {8292 const val = switch (air_tag) {
8229 .shl_exact => val: {8293 .shl_exact => val: {
8230 const shifted = try lhs_val.shl(rhs_val, lhs_ty, sema.arena);8294 const shifted = try lhs_val.shl(rhs_val, lhs_ty, sema.arena, target);
8231 if (scalar_ty.zigTypeTag() == .ComptimeInt) {8295 if (scalar_ty.zigTypeTag() == .ComptimeInt) {
8232 break :val shifted;8296 break :val shifted;
8233 }8297 }
8234 const int_info = scalar_ty.intInfo(target);8298 const int_info = scalar_ty.intInfo(target);
8235 const truncated = try shifted.intTrunc(lhs_ty, sema.arena, int_info.signedness, int_info.bits);8299 const truncated = try shifted.intTrunc(lhs_ty, sema.arena, int_info.signedness, int_info.bits, target);
8236 if (truncated.compare(.eq, shifted, lhs_ty)) {8300 if (truncated.compare(.eq, shifted, lhs_ty, target)) {
8237 break :val shifted;8301 break :val shifted;
8238 }8302 }
8239 return sema.addConstUndef(lhs_ty);8303 return sema.addConstUndef(lhs_ty);
8240 },8304 },
82418305
8242 .shl_sat => if (scalar_ty.zigTypeTag() == .ComptimeInt)8306 .shl_sat => if (scalar_ty.zigTypeTag() == .ComptimeInt)
8243 try lhs_val.shl(rhs_val, lhs_ty, sema.arena)8307 try lhs_val.shl(rhs_val, lhs_ty, sema.arena, target)
8244 else8308 else
8245 try lhs_val.shlSat(rhs_val, lhs_ty, sema.arena, target),8309 try lhs_val.shlSat(rhs_val, lhs_ty, sema.arena, target),
82468310
8247 .shl => if (scalar_ty.zigTypeTag() == .ComptimeInt)8311 .shl => if (scalar_ty.zigTypeTag() == .ComptimeInt)
8248 try lhs_val.shl(rhs_val, lhs_ty, sema.arena)8312 try lhs_val.shl(rhs_val, lhs_ty, sema.arena, target)
8249 else8313 else
8250 try lhs_val.shlTrunc(rhs_val, lhs_ty, sema.arena, target),8314 try lhs_val.shlTrunc(rhs_val, lhs_ty, sema.arena, target),
82518315
...@@ -8296,6 +8360,7 @@ fn zirShr(...@@ -8296,6 +8360,7 @@ fn zirShr(
8296 const lhs_ty = sema.typeOf(lhs);8360 const lhs_ty = sema.typeOf(lhs);
8297 const rhs_ty = sema.typeOf(rhs);8361 const rhs_ty = sema.typeOf(rhs);
8298 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);8362 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);
8363 const target = sema.mod.getTarget();
82998364
8300 const runtime_src = if (try sema.resolveMaybeUndefVal(block, rhs_src, rhs)) |rhs_val| rs: {8365 const runtime_src = if (try sema.resolveMaybeUndefVal(block, rhs_src, rhs)) |rhs_val| rs: {
8301 if (try sema.resolveMaybeUndefVal(block, lhs_src, lhs)) |lhs_val| {8366 if (try sema.resolveMaybeUndefVal(block, lhs_src, lhs)) |lhs_val| {
...@@ -8308,12 +8373,12 @@ fn zirShr(...@@ -8308,12 +8373,12 @@ fn zirShr(
8308 }8373 }
8309 if (air_tag == .shr_exact) {8374 if (air_tag == .shr_exact) {
8310 // Detect if any ones would be shifted out.8375 // Detect if any ones would be shifted out.
8311 const truncated = try lhs_val.intTruncBitsAsValue(lhs_ty, sema.arena, .unsigned, rhs_val);8376 const truncated = try lhs_val.intTruncBitsAsValue(lhs_ty, sema.arena, .unsigned, rhs_val, target);
8312 if (!truncated.compareWithZero(.eq)) {8377 if (!truncated.compareWithZero(.eq)) {
8313 return sema.addConstUndef(lhs_ty);8378 return sema.addConstUndef(lhs_ty);
8314 }8379 }
8315 }8380 }
8316 const val = try lhs_val.shr(rhs_val, lhs_ty, sema.arena);8381 const val = try lhs_val.shr(rhs_val, lhs_ty, sema.arena, target);
8317 return sema.addConstant(lhs_ty, val);8382 return sema.addConstant(lhs_ty, val);
8318 } else {8383 } else {
8319 // Even if lhs is not comptime known, we can still deduce certain things based8384 // Even if lhs is not comptime known, we can still deduce certain things based
...@@ -8359,6 +8424,7 @@ fn zirBitwise(...@@ -8359,6 +8424,7 @@ fn zirBitwise(
8359 const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src);8424 const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src);
83608425
8361 const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt;8426 const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt;
8427 const target = sema.mod.getTarget();
83628428
8363 if (!is_int) {8429 if (!is_int) {
8364 return sema.fail(block, src, "invalid operands to binary bitwise expression: '{s}' and '{s}'", .{ @tagName(lhs_ty.zigTypeTag()), @tagName(rhs_ty.zigTypeTag()) });8430 return sema.fail(block, src, "invalid operands to binary bitwise expression: '{s}' and '{s}'", .{ @tagName(lhs_ty.zigTypeTag()), @tagName(rhs_ty.zigTypeTag()) });
...@@ -8367,9 +8433,9 @@ fn zirBitwise(...@@ -8367,9 +8433,9 @@ fn zirBitwise(
8367 if (try sema.resolveMaybeUndefVal(block, lhs_src, casted_lhs)) |lhs_val| {8433 if (try sema.resolveMaybeUndefVal(block, lhs_src, casted_lhs)) |lhs_val| {
8368 if (try sema.resolveMaybeUndefVal(block, rhs_src, casted_rhs)) |rhs_val| {8434 if (try sema.resolveMaybeUndefVal(block, rhs_src, casted_rhs)) |rhs_val| {
8369 const result_val = switch (air_tag) {8435 const result_val = switch (air_tag) {
8370 .bit_and => try lhs_val.bitwiseAnd(rhs_val, resolved_type, sema.arena),8436 .bit_and => try lhs_val.bitwiseAnd(rhs_val, resolved_type, sema.arena, target),
8371 .bit_or => try lhs_val.bitwiseOr(rhs_val, resolved_type, sema.arena),8437 .bit_or => try lhs_val.bitwiseOr(rhs_val, resolved_type, sema.arena, target),
8372 .xor => try lhs_val.bitwiseXor(rhs_val, resolved_type, sema.arena),8438 .xor => try lhs_val.bitwiseXor(rhs_val, resolved_type, sema.arena, target),
8373 else => unreachable,8439 else => unreachable,
8374 };8440 };
8375 return sema.addConstant(resolved_type, result_val);8441 return sema.addConstant(resolved_type, result_val);
...@@ -8391,13 +8457,15 @@ fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -8391,13 +8457,15 @@ fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
8391 const operand = sema.resolveInst(inst_data.operand);8457 const operand = sema.resolveInst(inst_data.operand);
8392 const operand_type = sema.typeOf(operand);8458 const operand_type = sema.typeOf(operand);
8393 const scalar_type = operand_type.scalarType();8459 const scalar_type = operand_type.scalarType();
8460 const target = sema.mod.getTarget();
83948461
8395 if (scalar_type.zigTypeTag() != .Int) {8462 if (scalar_type.zigTypeTag() != .Int) {
8396 return sema.fail(block, src, "unable to perform binary not operation on type '{}'", .{operand_type});8463 return sema.fail(block, src, "unable to perform binary not operation on type '{}'", .{
8464 operand_type.fmt(target),
8465 });
8397 }8466 }
83988467
8399 if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |val| {8468 if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |val| {
8400 const target = sema.mod.getTarget();
8401 if (val.isUndef()) {8469 if (val.isUndef()) {
8402 return sema.addConstUndef(operand_type);8470 return sema.addConstUndef(operand_type);
8403 } else if (operand_type.zigTypeTag() == .Vector) {8471 } else if (operand_type.zigTypeTag() == .Vector) {
...@@ -8513,19 +8581,22 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -8513,19 +8581,22 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
8513 const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };8581 const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };
8514 const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };8582 const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };
85158583
8584 const target = sema.mod.getTarget();
8516 const lhs_info = (try sema.getArrayCatInfo(block, lhs_src, lhs)) orelse8585 const lhs_info = (try sema.getArrayCatInfo(block, lhs_src, lhs)) orelse
8517 return sema.fail(block, lhs_src, "expected array, found '{}'", .{lhs_ty});8586 return sema.fail(block, lhs_src, "expected array, found '{}'", .{lhs_ty.fmt(target)});
8518 const rhs_info = (try sema.getArrayCatInfo(block, rhs_src, rhs)) orelse8587 const rhs_info = (try sema.getArrayCatInfo(block, rhs_src, rhs)) orelse
8519 return sema.fail(block, rhs_src, "expected array, found '{}'", .{rhs_ty});8588 return sema.fail(block, rhs_src, "expected array, found '{}'", .{rhs_ty.fmt(target)});
8520 if (!lhs_info.elem_type.eql(rhs_info.elem_type)) {8589 if (!lhs_info.elem_type.eql(rhs_info.elem_type, target)) {
8521 return sema.fail(block, rhs_src, "expected array of type '{}', found '{}'", .{ lhs_info.elem_type, rhs_ty });8590 return sema.fail(block, rhs_src, "expected array of type '{}', found '{}'", .{
8591 lhs_info.elem_type.fmt(target), rhs_ty.fmt(target),
8592 });
8522 }8593 }
85238594
8524 // When there is a sentinel mismatch, no sentinel on the result. The type system8595 // When there is a sentinel mismatch, no sentinel on the result. The type system
8525 // will catch this if it is a problem.8596 // will catch this if it is a problem.
8526 var res_sent: ?Value = null;8597 var res_sent: ?Value = null;
8527 if (rhs_info.sentinel != null and lhs_info.sentinel != null) {8598 if (rhs_info.sentinel != null and lhs_info.sentinel != null) {
8528 if (rhs_info.sentinel.?.eql(lhs_info.sentinel.?, lhs_info.elem_type)) {8599 if (rhs_info.sentinel.?.eql(lhs_info.sentinel.?, lhs_info.elem_type, target)) {
8529 res_sent = lhs_info.sentinel.?;8600 res_sent = lhs_info.sentinel.?;
8530 }8601 }
8531 }8602 }
...@@ -8586,6 +8657,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -8586,6 +8657,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
85868657
8587fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, inst: Air.Inst.Ref) !?Type.ArrayInfo {8658fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, inst: Air.Inst.Ref) !?Type.ArrayInfo {
8588 const t = sema.typeOf(inst);8659 const t = sema.typeOf(inst);
8660 const target = sema.mod.getTarget();
8589 return switch (t.zigTypeTag()) {8661 return switch (t.zigTypeTag()) {
8590 .Array => t.arrayInfo(),8662 .Array => t.arrayInfo(),
8591 .Pointer => blk: {8663 .Pointer => blk: {
...@@ -8595,7 +8667,7 @@ fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, inst: Air.Inst.R...@@ -8595,7 +8667,7 @@ fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, inst: Air.Inst.R
8595 return Type.ArrayInfo{8667 return Type.ArrayInfo{
8596 .elem_type = t.childType(),8668 .elem_type = t.childType(),
8597 .sentinel = t.sentinel(),8669 .sentinel = t.sentinel(),
8598 .len = val.sliceLen(),8670 .len = val.sliceLen(target),
8599 };8671 };
8600 }8672 }
8601 if (ptrinfo.pointee_type.zigTypeTag() != .Array) return null;8673 if (ptrinfo.pointee_type.zigTypeTag() != .Array) return null;
...@@ -8691,9 +8763,10 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -8691,9 +8763,10 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
8691 if (lhs_ty.isTuple()) {8763 if (lhs_ty.isTuple()) {
8692 return sema.analyzeTupleMul(block, inst_data.src_node, lhs, factor);8764 return sema.analyzeTupleMul(block, inst_data.src_node, lhs, factor);
8693 }8765 }
8766 const target = sema.mod.getTarget();
86948767
8695 const mulinfo = (try sema.getArrayCatInfo(block, lhs_src, lhs)) orelse8768 const mulinfo = (try sema.getArrayCatInfo(block, lhs_src, lhs)) orelse
8696 return sema.fail(block, lhs_src, "expected array, found '{}'", .{lhs_ty});8769 return sema.fail(block, lhs_src, "expected array, found '{}'", .{lhs_ty.fmt(target)});
86978770
8698 const final_len_u64 = std.math.mul(u64, mulinfo.len, factor) catch8771 const final_len_u64 = std.math.mul(u64, mulinfo.len, factor) catch
8699 return sema.fail(block, rhs_src, "operation results in overflow", .{});8772 return sema.fail(block, rhs_src, "operation results in overflow", .{});
...@@ -8771,8 +8844,9 @@ fn zirNegate(...@@ -8771,8 +8844,9 @@ fn zirNegate(
8771 const rhs_ty = sema.typeOf(rhs);8844 const rhs_ty = sema.typeOf(rhs);
8772 const rhs_scalar_ty = rhs_ty.scalarType();8845 const rhs_scalar_ty = rhs_ty.scalarType();
87738846
8847 const target = sema.mod.getTarget();
8774 if (tag_override == .sub and rhs_scalar_ty.isUnsignedInt()) {8848 if (tag_override == .sub and rhs_scalar_ty.isUnsignedInt()) {
8775 return sema.fail(block, src, "negation of type '{}'", .{rhs_ty});8849 return sema.fail(block, src, "negation of type '{}'", .{rhs_ty.fmt(target)});
8776 }8850 }
87778851
8778 const lhs = if (rhs_ty.zigTypeTag() == .Vector)8852 const lhs = if (rhs_ty.zigTypeTag() == .Vector)
...@@ -8824,15 +8898,14 @@ fn zirOverflowArithmetic(...@@ -8824,15 +8898,14 @@ fn zirOverflowArithmetic(
8824 const ptr = sema.resolveInst(extra.ptr);8898 const ptr = sema.resolveInst(extra.ptr);
88258899
8826 const lhs_ty = sema.typeOf(lhs);8900 const lhs_ty = sema.typeOf(lhs);
8901 const target = sema.mod.getTarget();
88278902
8828 // Note, the types of lhs/rhs (also for shifting)/ptr are already correct as ensured by astgen.8903 // Note, the types of lhs/rhs (also for shifting)/ptr are already correct as ensured by astgen.
8829 const dest_ty = lhs_ty;8904 const dest_ty = lhs_ty;
8830 if (dest_ty.zigTypeTag() != .Int) {8905 if (dest_ty.zigTypeTag() != .Int) {
8831 return sema.fail(block, src, "expected integer type, found '{}'", .{dest_ty});8906 return sema.fail(block, src, "expected integer type, found '{}'", .{dest_ty.fmt(target)});
8832 }8907 }
88338908
8834 const target = sema.mod.getTarget();
8835
8836 const maybe_lhs_val = try sema.resolveMaybeUndefVal(block, lhs_src, lhs);8909 const maybe_lhs_val = try sema.resolveMaybeUndefVal(block, lhs_src, lhs);
8837 const maybe_rhs_val = try sema.resolveMaybeUndefVal(block, rhs_src, rhs);8910 const maybe_rhs_val = try sema.resolveMaybeUndefVal(block, rhs_src, rhs);
88388911
...@@ -8894,7 +8967,7 @@ fn zirOverflowArithmetic(...@@ -8894,7 +8967,7 @@ fn zirOverflowArithmetic(
8894 if (!lhs_val.isUndef()) {8967 if (!lhs_val.isUndef()) {
8895 if (lhs_val.compareWithZero(.eq)) {8968 if (lhs_val.compareWithZero(.eq)) {
8896 break :result .{ .overflowed = .no, .wrapped = lhs };8969 break :result .{ .overflowed = .no, .wrapped = lhs };
8897 } else if (lhs_val.compare(.eq, Value.one, dest_ty)) {8970 } else if (lhs_val.compare(.eq, Value.one, dest_ty, target)) {
8898 break :result .{ .overflowed = .no, .wrapped = rhs };8971 break :result .{ .overflowed = .no, .wrapped = rhs };
8899 }8972 }
8900 }8973 }
...@@ -8904,7 +8977,7 @@ fn zirOverflowArithmetic(...@@ -8904,7 +8977,7 @@ fn zirOverflowArithmetic(
8904 if (!rhs_val.isUndef()) {8977 if (!rhs_val.isUndef()) {
8905 if (rhs_val.compareWithZero(.eq)) {8978 if (rhs_val.compareWithZero(.eq)) {
8906 break :result .{ .overflowed = .no, .wrapped = rhs };8979 break :result .{ .overflowed = .no, .wrapped = rhs };
8907 } else if (rhs_val.compare(.eq, Value.one, dest_ty)) {8980 } else if (rhs_val.compare(.eq, Value.one, dest_ty, target)) {
8908 break :result .{ .overflowed = .no, .wrapped = lhs };8981 break :result .{ .overflowed = .no, .wrapped = lhs };
8909 }8982 }
8910 }8983 }
...@@ -9079,7 +9152,7 @@ fn analyzeArithmetic(...@@ -9079,7 +9152,7 @@ fn analyzeArithmetic(
9079 if (is_int) {9152 if (is_int) {
9080 return sema.addConstant(9153 return sema.addConstant(
9081 resolved_type,9154 resolved_type,
9082 try lhs_val.intAdd(rhs_val, resolved_type, sema.arena),9155 try lhs_val.intAdd(rhs_val, resolved_type, sema.arena, target),
9083 );9156 );
9084 } else {9157 } else {
9085 return sema.addConstant(9158 return sema.addConstant(
...@@ -9132,7 +9205,7 @@ fn analyzeArithmetic(...@@ -9132,7 +9205,7 @@ fn analyzeArithmetic(
9132 }9205 }
9133 if (maybe_lhs_val) |lhs_val| {9206 if (maybe_lhs_val) |lhs_val| {
9134 const val = if (scalar_tag == .ComptimeInt)9207 const val = if (scalar_tag == .ComptimeInt)
9135 try lhs_val.intAdd(rhs_val, resolved_type, sema.arena)9208 try lhs_val.intAdd(rhs_val, resolved_type, sema.arena, target)
9136 else9209 else
9137 try lhs_val.intAddSat(rhs_val, resolved_type, sema.arena, target);9210 try lhs_val.intAddSat(rhs_val, resolved_type, sema.arena, target);
91389211
...@@ -9172,7 +9245,7 @@ fn analyzeArithmetic(...@@ -9172,7 +9245,7 @@ fn analyzeArithmetic(
9172 if (is_int) {9245 if (is_int) {
9173 return sema.addConstant(9246 return sema.addConstant(
9174 resolved_type,9247 resolved_type,
9175 try lhs_val.intSub(rhs_val, resolved_type, sema.arena),9248 try lhs_val.intSub(rhs_val, resolved_type, sema.arena, target),
9176 );9249 );
9177 } else {9250 } else {
9178 return sema.addConstant(9251 return sema.addConstant(
...@@ -9225,7 +9298,7 @@ fn analyzeArithmetic(...@@ -9225,7 +9298,7 @@ fn analyzeArithmetic(
9225 }9298 }
9226 if (maybe_rhs_val) |rhs_val| {9299 if (maybe_rhs_val) |rhs_val| {
9227 const val = if (scalar_tag == .ComptimeInt)9300 const val = if (scalar_tag == .ComptimeInt)
9228 try lhs_val.intSub(rhs_val, resolved_type, sema.arena)9301 try lhs_val.intSub(rhs_val, resolved_type, sema.arena, target)
9229 else9302 else
9230 try lhs_val.intSubSat(rhs_val, resolved_type, sema.arena, target);9303 try lhs_val.intSubSat(rhs_val, resolved_type, sema.arena, target);
92319304
...@@ -9275,7 +9348,7 @@ fn analyzeArithmetic(...@@ -9275,7 +9348,7 @@ fn analyzeArithmetic(
9275 if (lhs_val.isUndef()) {9348 if (lhs_val.isUndef()) {
9276 if (lhs_scalar_ty.isSignedInt() and rhs_scalar_ty.isSignedInt()) {9349 if (lhs_scalar_ty.isSignedInt() and rhs_scalar_ty.isSignedInt()) {
9277 if (maybe_rhs_val) |rhs_val| {9350 if (maybe_rhs_val) |rhs_val| {
9278 if (rhs_val.compare(.neq, Value.negative_one, rhs_ty)) {9351 if (rhs_val.compare(.neq, Value.negative_one, rhs_ty, target)) {
9279 return sema.addConstUndef(resolved_type);9352 return sema.addConstUndef(resolved_type);
9280 }9353 }
9281 }9354 }
...@@ -9288,7 +9361,7 @@ fn analyzeArithmetic(...@@ -9288,7 +9361,7 @@ fn analyzeArithmetic(
9288 if (is_int) {9361 if (is_int) {
9289 return sema.addConstant(9362 return sema.addConstant(
9290 resolved_type,9363 resolved_type,
9291 try lhs_val.intDiv(rhs_val, resolved_type, sema.arena),9364 try lhs_val.intDiv(rhs_val, resolved_type, sema.arena, target),
9292 );9365 );
9293 } else {9366 } else {
9294 return sema.addConstant(9367 return sema.addConstant(
...@@ -9350,7 +9423,7 @@ fn analyzeArithmetic(...@@ -9350,7 +9423,7 @@ fn analyzeArithmetic(
9350 if (lhs_val.isUndef()) {9423 if (lhs_val.isUndef()) {
9351 if (lhs_scalar_ty.isSignedInt() and rhs_scalar_ty.isSignedInt()) {9424 if (lhs_scalar_ty.isSignedInt() and rhs_scalar_ty.isSignedInt()) {
9352 if (maybe_rhs_val) |rhs_val| {9425 if (maybe_rhs_val) |rhs_val| {
9353 if (rhs_val.compare(.neq, Value.negative_one, rhs_ty)) {9426 if (rhs_val.compare(.neq, Value.negative_one, rhs_ty, target)) {
9354 return sema.addConstUndef(resolved_type);9427 return sema.addConstUndef(resolved_type);
9355 }9428 }
9356 }9429 }
...@@ -9363,7 +9436,7 @@ fn analyzeArithmetic(...@@ -9363,7 +9436,7 @@ fn analyzeArithmetic(
9363 if (is_int) {9436 if (is_int) {
9364 return sema.addConstant(9437 return sema.addConstant(
9365 resolved_type,9438 resolved_type,
9366 try lhs_val.intDiv(rhs_val, resolved_type, sema.arena),9439 try lhs_val.intDiv(rhs_val, resolved_type, sema.arena, target),
9367 );9440 );
9368 } else {9441 } else {
9369 return sema.addConstant(9442 return sema.addConstant(
...@@ -9413,7 +9486,7 @@ fn analyzeArithmetic(...@@ -9413,7 +9486,7 @@ fn analyzeArithmetic(
9413 if (lhs_val.isUndef()) {9486 if (lhs_val.isUndef()) {
9414 if (lhs_scalar_ty.isSignedInt() and rhs_scalar_ty.isSignedInt()) {9487 if (lhs_scalar_ty.isSignedInt() and rhs_scalar_ty.isSignedInt()) {
9415 if (maybe_rhs_val) |rhs_val| {9488 if (maybe_rhs_val) |rhs_val| {
9416 if (rhs_val.compare(.neq, Value.negative_one, rhs_ty)) {9489 if (rhs_val.compare(.neq, Value.negative_one, rhs_ty, target)) {
9417 return sema.addConstUndef(resolved_type);9490 return sema.addConstUndef(resolved_type);
9418 }9491 }
9419 }9492 }
...@@ -9426,7 +9499,7 @@ fn analyzeArithmetic(...@@ -9426,7 +9499,7 @@ fn analyzeArithmetic(
9426 if (is_int) {9499 if (is_int) {
9427 return sema.addConstant(9500 return sema.addConstant(
9428 resolved_type,9501 resolved_type,
9429 try lhs_val.intDivFloor(rhs_val, resolved_type, sema.arena),9502 try lhs_val.intDivFloor(rhs_val, resolved_type, sema.arena, target),
9430 );9503 );
9431 } else {9504 } else {
9432 return sema.addConstant(9505 return sema.addConstant(
...@@ -9477,7 +9550,7 @@ fn analyzeArithmetic(...@@ -9477,7 +9550,7 @@ fn analyzeArithmetic(
9477 // TODO: emit compile error if there is a remainder9550 // TODO: emit compile error if there is a remainder
9478 return sema.addConstant(9551 return sema.addConstant(
9479 resolved_type,9552 resolved_type,
9480 try lhs_val.intDiv(rhs_val, resolved_type, sema.arena),9553 try lhs_val.intDiv(rhs_val, resolved_type, sema.arena, target),
9481 );9554 );
9482 } else {9555 } else {
9483 // TODO: emit compile error if there is a remainder9556 // TODO: emit compile error if there is a remainder
...@@ -9503,7 +9576,7 @@ fn analyzeArithmetic(...@@ -9503,7 +9576,7 @@ fn analyzeArithmetic(
9503 if (lhs_val.compareWithZero(.eq)) {9576 if (lhs_val.compareWithZero(.eq)) {
9504 return sema.addConstant(resolved_type, Value.zero);9577 return sema.addConstant(resolved_type, Value.zero);
9505 }9578 }
9506 if (lhs_val.compare(.eq, Value.one, lhs_ty)) {9579 if (lhs_val.compare(.eq, Value.one, lhs_ty, target)) {
9507 return casted_rhs;9580 return casted_rhs;
9508 }9581 }
9509 }9582 }
...@@ -9519,7 +9592,7 @@ fn analyzeArithmetic(...@@ -9519,7 +9592,7 @@ fn analyzeArithmetic(
9519 if (rhs_val.compareWithZero(.eq)) {9592 if (rhs_val.compareWithZero(.eq)) {
9520 return sema.addConstant(resolved_type, Value.zero);9593 return sema.addConstant(resolved_type, Value.zero);
9521 }9594 }
9522 if (rhs_val.compare(.eq, Value.one, rhs_ty)) {9595 if (rhs_val.compare(.eq, Value.one, rhs_ty, target)) {
9523 return casted_lhs;9596 return casted_lhs;
9524 }9597 }
9525 if (maybe_lhs_val) |lhs_val| {9598 if (maybe_lhs_val) |lhs_val| {
...@@ -9533,7 +9606,7 @@ fn analyzeArithmetic(...@@ -9533,7 +9606,7 @@ fn analyzeArithmetic(
9533 if (is_int) {9606 if (is_int) {
9534 return sema.addConstant(9607 return sema.addConstant(
9535 resolved_type,9608 resolved_type,
9536 try lhs_val.intMul(rhs_val, resolved_type, sema.arena),9609 try lhs_val.intMul(rhs_val, resolved_type, sema.arena, target),
9537 );9610 );
9538 } else {9611 } else {
9539 return sema.addConstant(9612 return sema.addConstant(
...@@ -9554,7 +9627,7 @@ fn analyzeArithmetic(...@@ -9554,7 +9627,7 @@ fn analyzeArithmetic(
9554 if (lhs_val.compareWithZero(.eq)) {9627 if (lhs_val.compareWithZero(.eq)) {
9555 return sema.addConstant(resolved_type, Value.zero);9628 return sema.addConstant(resolved_type, Value.zero);
9556 }9629 }
9557 if (lhs_val.compare(.eq, Value.one, lhs_ty)) {9630 if (lhs_val.compare(.eq, Value.one, lhs_ty, target)) {
9558 return casted_rhs;9631 return casted_rhs;
9559 }9632 }
9560 }9633 }
...@@ -9566,7 +9639,7 @@ fn analyzeArithmetic(...@@ -9566,7 +9639,7 @@ fn analyzeArithmetic(
9566 if (rhs_val.compareWithZero(.eq)) {9639 if (rhs_val.compareWithZero(.eq)) {
9567 return sema.addConstant(resolved_type, Value.zero);9640 return sema.addConstant(resolved_type, Value.zero);
9568 }9641 }
9569 if (rhs_val.compare(.eq, Value.one, rhs_ty)) {9642 if (rhs_val.compare(.eq, Value.one, rhs_ty, target)) {
9570 return casted_lhs;9643 return casted_lhs;
9571 }9644 }
9572 if (maybe_lhs_val) |lhs_val| {9645 if (maybe_lhs_val) |lhs_val| {
...@@ -9590,7 +9663,7 @@ fn analyzeArithmetic(...@@ -9590,7 +9663,7 @@ fn analyzeArithmetic(
9590 if (lhs_val.compareWithZero(.eq)) {9663 if (lhs_val.compareWithZero(.eq)) {
9591 return sema.addConstant(resolved_type, Value.zero);9664 return sema.addConstant(resolved_type, Value.zero);
9592 }9665 }
9593 if (lhs_val.compare(.eq, Value.one, lhs_ty)) {9666 if (lhs_val.compare(.eq, Value.one, lhs_ty, target)) {
9594 return casted_rhs;9667 return casted_rhs;
9595 }9668 }
9596 }9669 }
...@@ -9602,7 +9675,7 @@ fn analyzeArithmetic(...@@ -9602,7 +9675,7 @@ fn analyzeArithmetic(
9602 if (rhs_val.compareWithZero(.eq)) {9675 if (rhs_val.compareWithZero(.eq)) {
9603 return sema.addConstant(resolved_type, Value.zero);9676 return sema.addConstant(resolved_type, Value.zero);
9604 }9677 }
9605 if (rhs_val.compare(.eq, Value.one, rhs_ty)) {9678 if (rhs_val.compare(.eq, Value.one, rhs_ty, target)) {
9606 return casted_lhs;9679 return casted_lhs;
9607 }9680 }
9608 if (maybe_lhs_val) |lhs_val| {9681 if (maybe_lhs_val) |lhs_val| {
...@@ -9611,7 +9684,7 @@ fn analyzeArithmetic(...@@ -9611,7 +9684,7 @@ fn analyzeArithmetic(
9611 }9684 }
96129685
9613 const val = if (scalar_tag == .ComptimeInt)9686 const val = if (scalar_tag == .ComptimeInt)
9614 try lhs_val.intMul(rhs_val, resolved_type, sema.arena)9687 try lhs_val.intMul(rhs_val, resolved_type, sema.arena, target)
9615 else9688 else
9616 try lhs_val.intMulSat(rhs_val, resolved_type, sema.arena, target);9689 try lhs_val.intMulSat(rhs_val, resolved_type, sema.arena, target);
96179690
...@@ -9652,7 +9725,7 @@ fn analyzeArithmetic(...@@ -9652,7 +9725,7 @@ fn analyzeArithmetic(
9652 return sema.failWithDivideByZero(block, rhs_src);9725 return sema.failWithDivideByZero(block, rhs_src);
9653 }9726 }
9654 if (maybe_lhs_val) |lhs_val| {9727 if (maybe_lhs_val) |lhs_val| {
9655 const rem_result = try lhs_val.intRem(rhs_val, resolved_type, sema.arena);9728 const rem_result = try lhs_val.intRem(rhs_val, resolved_type, sema.arena, target);
9656 // If this answer could possibly be different by doing `intMod`,9729 // If this answer could possibly be different by doing `intMod`,
9657 // we must emit a compile error. Otherwise, it's OK.9730 // we must emit a compile error. Otherwise, it's OK.
9658 if (rhs_val.compareWithZero(.lt) != lhs_val.compareWithZero(.lt) and9731 if (rhs_val.compareWithZero(.lt) != lhs_val.compareWithZero(.lt) and
...@@ -9731,7 +9804,7 @@ fn analyzeArithmetic(...@@ -9731,7 +9804,7 @@ fn analyzeArithmetic(
9731 if (maybe_lhs_val) |lhs_val| {9804 if (maybe_lhs_val) |lhs_val| {
9732 return sema.addConstant(9805 return sema.addConstant(
9733 resolved_type,9806 resolved_type,
9734 try lhs_val.intRem(rhs_val, resolved_type, sema.arena),9807 try lhs_val.intRem(rhs_val, resolved_type, sema.arena, target),
9735 );9808 );
9736 }9809 }
9737 break :rs .{ .src = lhs_src, .air_tag = .rem };9810 break :rs .{ .src = lhs_src, .air_tag = .rem };
...@@ -9788,7 +9861,7 @@ fn analyzeArithmetic(...@@ -9788,7 +9861,7 @@ fn analyzeArithmetic(
9788 if (maybe_lhs_val) |lhs_val| {9861 if (maybe_lhs_val) |lhs_val| {
9789 return sema.addConstant(9862 return sema.addConstant(
9790 resolved_type,9863 resolved_type,
9791 try lhs_val.intMod(rhs_val, resolved_type, sema.arena),9864 try lhs_val.intMod(rhs_val, resolved_type, sema.arena, target),
9792 );9865 );
9793 }9866 }
9794 break :rs .{ .src = lhs_src, .air_tag = .mod };9867 break :rs .{ .src = lhs_src, .air_tag = .mod };
...@@ -9839,6 +9912,7 @@ fn analyzePtrArithmetic(...@@ -9839,6 +9912,7 @@ fn analyzePtrArithmetic(
9839 // coerce to isize instead of usize.9912 // coerce to isize instead of usize.
9840 const offset = try sema.coerce(block, Type.usize, uncasted_offset, offset_src);9913 const offset = try sema.coerce(block, Type.usize, uncasted_offset, offset_src);
9841 // TODO adjust the return type according to alignment and other factors9914 // TODO adjust the return type according to alignment and other factors
9915 const target = sema.mod.getTarget();
9842 const runtime_src = rs: {9916 const runtime_src = rs: {
9843 if (try sema.resolveMaybeUndefVal(block, ptr_src, ptr)) |ptr_val| {9917 if (try sema.resolveMaybeUndefVal(block, ptr_src, ptr)) |ptr_val| {
9844 if (try sema.resolveMaybeUndefVal(block, offset_src, offset)) |offset_val| {9918 if (try sema.resolveMaybeUndefVal(block, offset_src, offset)) |offset_val| {
...@@ -9849,11 +9923,10 @@ fn analyzePtrArithmetic(...@@ -9849,11 +9923,10 @@ fn analyzePtrArithmetic(
9849 return sema.addConstUndef(new_ptr_ty);9923 return sema.addConstUndef(new_ptr_ty);
9850 }9924 }
98519925
9852 const offset_int = try sema.usizeCast(block, offset_src, offset_val.toUnsignedInt());9926 const offset_int = try sema.usizeCast(block, offset_src, offset_val.toUnsignedInt(target));
9853 // TODO I tried to put this check earlier but it the LLVM backend generate invalid instructinons9927 // TODO I tried to put this check earlier but it the LLVM backend generate invalid instructinons
9854 if (offset_int == 0) return ptr;9928 if (offset_int == 0) return ptr;
9855 if (ptr_val.getUnsignedInt()) |addr| {9929 if (ptr_val.getUnsignedInt(target)) |addr| {
9856 const target = sema.mod.getTarget();
9857 const ptr_child_ty = ptr_ty.childType();9930 const ptr_child_ty = ptr_ty.childType();
9858 const elem_ty = if (ptr_ty.isSinglePointer() and ptr_child_ty.zigTypeTag() == .Array)9931 const elem_ty = if (ptr_ty.isSinglePointer() and ptr_child_ty.zigTypeTag() == .Array)
9859 ptr_child_ty.childType()9932 ptr_child_ty.childType()
...@@ -9872,7 +9945,7 @@ fn analyzePtrArithmetic(...@@ -9872,7 +9945,7 @@ fn analyzePtrArithmetic(
9872 if (air_tag == .ptr_sub) {9945 if (air_tag == .ptr_sub) {
9873 return sema.fail(block, op_src, "TODO implement Sema comptime pointer subtraction", .{});9946 return sema.fail(block, op_src, "TODO implement Sema comptime pointer subtraction", .{});
9874 }9947 }
9875 const new_ptr_val = try ptr_val.elemPtr(ptr_ty, sema.arena, offset_int);9948 const new_ptr_val = try ptr_val.elemPtr(ptr_ty, sema.arena, offset_int, target);
9876 return sema.addConstant(new_ptr_ty, new_ptr_val);9949 return sema.addConstant(new_ptr_ty, new_ptr_val);
9877 } else break :rs offset_src;9950 } else break :rs offset_src;
9878 } else break :rs ptr_src;9951 } else break :rs ptr_src;
...@@ -10035,6 +10108,7 @@ fn zirCmpEq(...@@ -10035,6 +10108,7 @@ fn zirCmpEq(
10035 const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };10108 const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };
10036 const lhs = sema.resolveInst(extra.lhs);10109 const lhs = sema.resolveInst(extra.lhs);
10037 const rhs = sema.resolveInst(extra.rhs);10110 const rhs = sema.resolveInst(extra.rhs);
10111 const target = sema.mod.getTarget();
1003810112
10039 const lhs_ty = sema.typeOf(lhs);10113 const lhs_ty = sema.typeOf(lhs);
10040 const rhs_ty = sema.typeOf(rhs);10114 const rhs_ty = sema.typeOf(rhs);
...@@ -10059,7 +10133,7 @@ fn zirCmpEq(...@@ -10059,7 +10133,7 @@ fn zirCmpEq(
1005910133
10060 if (lhs_ty_tag == .Null or rhs_ty_tag == .Null) {10134 if (lhs_ty_tag == .Null or rhs_ty_tag == .Null) {
10061 const non_null_type = if (lhs_ty_tag == .Null) rhs_ty else lhs_ty;10135 const non_null_type = if (lhs_ty_tag == .Null) rhs_ty else lhs_ty;
10062 return sema.fail(block, src, "comparison of '{}' with null", .{non_null_type});10136 return sema.fail(block, src, "comparison of '{}' with null", .{non_null_type.fmt(target)});
10063 }10137 }
1006410138
10065 if (lhs_ty_tag == .Union and (rhs_ty_tag == .EnumLiteral or rhs_ty_tag == .Enum)) {10139 if (lhs_ty_tag == .Union and (rhs_ty_tag == .EnumLiteral or rhs_ty_tag == .Enum)) {
...@@ -10099,7 +10173,7 @@ fn zirCmpEq(...@@ -10099,7 +10173,7 @@ fn zirCmpEq(
10099 if (lhs_ty_tag == .Type and rhs_ty_tag == .Type) {10173 if (lhs_ty_tag == .Type and rhs_ty_tag == .Type) {
10100 const lhs_as_type = try sema.analyzeAsType(block, lhs_src, lhs);10174 const lhs_as_type = try sema.analyzeAsType(block, lhs_src, lhs);
10101 const rhs_as_type = try sema.analyzeAsType(block, rhs_src, rhs);10175 const rhs_as_type = try sema.analyzeAsType(block, rhs_src, rhs);
10102 if (lhs_as_type.eql(rhs_as_type) == (op == .eq)) {10176 if (lhs_as_type.eql(rhs_as_type, target) == (op == .eq)) {
10103 return Air.Inst.Ref.bool_true;10177 return Air.Inst.Ref.bool_true;
10104 } else {10178 } else {
10105 return Air.Inst.Ref.bool_false;10179 return Air.Inst.Ref.bool_false;
...@@ -10176,9 +10250,10 @@ fn analyzeCmp(...@@ -10176,9 +10250,10 @@ fn analyzeCmp(
10176 }10250 }
10177 const instructions = &[_]Air.Inst.Ref{ lhs, rhs };10251 const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
10178 const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{ .override = &[_]LazySrcLoc{ lhs_src, rhs_src } });10252 const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{ .override = &[_]LazySrcLoc{ lhs_src, rhs_src } });
10253 const target = sema.mod.getTarget();
10179 if (!resolved_type.isSelfComparable(is_equality_cmp)) {10254 if (!resolved_type.isSelfComparable(is_equality_cmp)) {
10180 return sema.fail(block, src, "{s} operator not allowed for type '{}'", .{10255 return sema.fail(block, src, "{s} operator not allowed for type '{}'", .{
10181 @tagName(op), resolved_type,10256 @tagName(op), resolved_type.fmt(target),
10182 });10257 });
10183 }10258 }
10184 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);10259 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);
...@@ -10196,6 +10271,7 @@ fn cmpSelf(...@@ -10196,6 +10271,7 @@ fn cmpSelf(
10196 rhs_src: LazySrcLoc,10271 rhs_src: LazySrcLoc,
10197) CompileError!Air.Inst.Ref {10272) CompileError!Air.Inst.Ref {
10198 const resolved_type = sema.typeOf(casted_lhs);10273 const resolved_type = sema.typeOf(casted_lhs);
10274 const target = sema.mod.getTarget();
10199 const runtime_src: LazySrcLoc = src: {10275 const runtime_src: LazySrcLoc = src: {
10200 if (try sema.resolveMaybeUndefVal(block, lhs_src, casted_lhs)) |lhs_val| {10276 if (try sema.resolveMaybeUndefVal(block, lhs_src, casted_lhs)) |lhs_val| {
10201 if (lhs_val.isUndef()) return sema.addConstUndef(Type.bool);10277 if (lhs_val.isUndef()) return sema.addConstUndef(Type.bool);
...@@ -10204,11 +10280,11 @@ fn cmpSelf(...@@ -10204,11 +10280,11 @@ fn cmpSelf(
1020410280
10205 if (resolved_type.zigTypeTag() == .Vector) {10281 if (resolved_type.zigTypeTag() == .Vector) {
10206 const result_ty = try Type.vector(sema.arena, resolved_type.vectorLen(), Type.@"bool");10282 const result_ty = try Type.vector(sema.arena, resolved_type.vectorLen(), Type.@"bool");
10207 const cmp_val = try lhs_val.compareVector(op, rhs_val, resolved_type, sema.arena);10283 const cmp_val = try lhs_val.compareVector(op, rhs_val, resolved_type, sema.arena, target);
10208 return sema.addConstant(result_ty, cmp_val);10284 return sema.addConstant(result_ty, cmp_val);
10209 }10285 }
1021010286
10211 if (lhs_val.compare(op, rhs_val, resolved_type)) {10287 if (lhs_val.compare(op, rhs_val, resolved_type, target)) {
10212 return Air.Inst.Ref.bool_true;10288 return Air.Inst.Ref.bool_true;
10213 } else {10289 } else {
10214 return Air.Inst.Ref.bool_false;10290 return Air.Inst.Ref.bool_false;
...@@ -10276,7 +10352,7 @@ fn zirSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -10276,7 +10352,7 @@ fn zirSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
10276 .Null,10352 .Null,
10277 .BoundFn,10353 .BoundFn,
10278 .Opaque,10354 .Opaque,
10279 => return sema.fail(block, src, "no size available for type '{}'", .{operand_ty}),10355 => return sema.fail(block, src, "no size available for type '{}'", .{operand_ty.fmt(target)}),
1028010356
10281 .Type,10357 .Type,
10282 .EnumLiteral,10358 .EnumLiteral,
...@@ -11365,11 +11441,12 @@ fn log2IntType(sema: *Sema, block: *Block, operand: Type, src: LazySrcLoc) Compi...@@ -11365,11 +11441,12 @@ fn log2IntType(sema: *Sema, block: *Block, operand: Type, src: LazySrcLoc) Compi
11365 },11441 },
11366 else => {},11442 else => {},
11367 }11443 }
11444 const target = sema.mod.getTarget();
11368 return sema.fail(11445 return sema.fail(
11369 block,11446 block,
11370 src,11447 src,
11371 "bit shifting operation expected integer type, found '{}'",11448 "bit shifting operation expected integer type, found '{}'",
11372 .{operand},11449 .{operand.fmt(target)},
11373 );11450 );
11374}11451}
1137511452
...@@ -12414,6 +12491,7 @@ fn fieldType(...@@ -12414,6 +12491,7 @@ fn fieldType(
12414 ty_src: LazySrcLoc,12491 ty_src: LazySrcLoc,
12415) CompileError!Air.Inst.Ref {12492) CompileError!Air.Inst.Ref {
12416 const resolved_ty = try sema.resolveTypeFields(block, ty_src, aggregate_ty);12493 const resolved_ty = try sema.resolveTypeFields(block, ty_src, aggregate_ty);
12494 const target = sema.mod.getTarget();
12417 switch (resolved_ty.zigTypeTag()) {12495 switch (resolved_ty.zigTypeTag()) {
12418 .Struct => {12496 .Struct => {
12419 const struct_obj = resolved_ty.castTag(.@"struct").?.data;12497 const struct_obj = resolved_ty.castTag(.@"struct").?.data;
...@@ -12428,7 +12506,7 @@ fn fieldType(...@@ -12428,7 +12506,7 @@ fn fieldType(
12428 return sema.addType(field.ty);12506 return sema.addType(field.ty);
12429 },12507 },
12430 else => return sema.fail(block, ty_src, "expected struct or union; found '{}'", .{12508 else => return sema.fail(block, ty_src, "expected struct or union; found '{}'", .{
12431 resolved_ty,12509 resolved_ty.fmt(target),
12432 }),12510 }),
12433 }12511 }
12434}12512}
...@@ -12459,11 +12537,11 @@ fn zirAlignOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -12459,11 +12537,11 @@ fn zirAlignOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
12459 const inst_data = sema.code.instructions.items(.data)[inst].un_node;12537 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
12460 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };12538 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
12461 const ty = try sema.resolveType(block, operand_src, inst_data.operand);12539 const ty = try sema.resolveType(block, operand_src, inst_data.operand);
12462 const resolved_ty = try sema.resolveTypeFields(block, operand_src, ty);
12463 try sema.resolveTypeLayout(block, operand_src, resolved_ty);
12464 const target = sema.mod.getTarget();12540 const target = sema.mod.getTarget();
12465 const abi_align = resolved_ty.abiAlignment(target);12541 return sema.addConstant(
12466 return sema.addIntUnsigned(Type.comptime_int, abi_align);12542 Type.comptime_int,
12543 try ty.lazyAbiAlignment(target, sema.arena),
12544 );
12467}12545}
1246812546
12469fn zirBoolToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {12547fn zirBoolToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
...@@ -12509,6 +12587,7 @@ fn zirUnaryMath(...@@ -12509,6 +12587,7 @@ fn zirUnaryMath(
12509 const operand = sema.resolveInst(inst_data.operand);12587 const operand = sema.resolveInst(inst_data.operand);
12510 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };12588 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
12511 const operand_ty = sema.typeOf(operand);12589 const operand_ty = sema.typeOf(operand);
12590 const target = sema.mod.getTarget();
1251212591
12513 switch (operand_ty.zigTypeTag()) {12592 switch (operand_ty.zigTypeTag()) {
12514 .ComptimeFloat, .Float => {},12593 .ComptimeFloat, .Float => {},
...@@ -12516,13 +12595,12 @@ fn zirUnaryMath(...@@ -12516,13 +12595,12 @@ fn zirUnaryMath(
12516 const scalar_ty = operand_ty.scalarType();12595 const scalar_ty = operand_ty.scalarType();
12517 switch (scalar_ty.zigTypeTag()) {12596 switch (scalar_ty.zigTypeTag()) {
12518 .ComptimeFloat, .Float => {},12597 .ComptimeFloat, .Float => {},
12519 else => return sema.fail(block, operand_src, "expected vector of floats or float type, found '{}'", .{scalar_ty}),12598 else => return sema.fail(block, operand_src, "expected vector of floats or float type, found '{}'", .{scalar_ty.fmt(target)}),
12520 }12599 }
12521 },12600 },
12522 else => return sema.fail(block, operand_src, "expected vector of floats or float type, found '{}'", .{operand_ty}),12601 else => return sema.fail(block, operand_src, "expected vector of floats or float type, found '{}'", .{operand_ty.fmt(target)}),
12523 }12602 }
1252412603
12525 const target = sema.mod.getTarget();
12526 switch (operand_ty.zigTypeTag()) {12604 switch (operand_ty.zigTypeTag()) {
12527 .Vector => {12605 .Vector => {
12528 const scalar_ty = operand_ty.scalarType();12606 const scalar_ty = operand_ty.scalarType();
...@@ -12568,6 +12646,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -12568,6 +12646,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
12568 const src = inst_data.src();12646 const src = inst_data.src();
12569 const operand = sema.resolveInst(inst_data.operand);12647 const operand = sema.resolveInst(inst_data.operand);
12570 const operand_ty = sema.typeOf(operand);12648 const operand_ty = sema.typeOf(operand);
12649 const target = sema.mod.getTarget();
1257112650
12572 try sema.resolveTypeLayout(block, operand_src, operand_ty);12651 try sema.resolveTypeLayout(block, operand_src, operand_ty);
12573 const enum_ty = switch (operand_ty.zigTypeTag()) {12652 const enum_ty = switch (operand_ty.zigTypeTag()) {
...@@ -12590,13 +12669,13 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -12590,13 +12669,13 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
12590 return sema.failWithOwnedErrorMsg(block, msg);12669 return sema.failWithOwnedErrorMsg(block, msg);
12591 },12670 },
12592 else => return sema.fail(block, operand_src, "expected enum or union; found {}", .{12671 else => return sema.fail(block, operand_src, "expected enum or union; found {}", .{
12593 operand_ty,12672 operand_ty.fmt(target),
12594 }),12673 }),
12595 };12674 };
12596 const enum_decl = enum_ty.getOwnerDecl();12675 const enum_decl = enum_ty.getOwnerDecl();
12597 const casted_operand = try sema.coerce(block, enum_ty, operand, operand_src);12676 const casted_operand = try sema.coerce(block, enum_ty, operand, operand_src);
12598 if (try sema.resolveDefinedValue(block, operand_src, casted_operand)) |val| {12677 if (try sema.resolveDefinedValue(block, operand_src, casted_operand)) |val| {
12599 const field_index = enum_ty.enumTagFieldIndex(val) orelse {12678 const field_index = enum_ty.enumTagFieldIndex(val, target) orelse {
12600 const msg = msg: {12679 const msg = msg: {
12601 const msg = try sema.errMsg(block, src, "no field with value {} in enum '{s}'", .{12680 const msg = try sema.errMsg(block, src, "no field with value {} in enum '{s}'", .{
12602 casted_operand, enum_decl.name,12681 casted_operand, enum_decl.name,
...@@ -12626,8 +12705,8 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -12626,8 +12705,8 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
12626 const val = try sema.resolveConstValue(block, operand_src, type_info);12705 const val = try sema.resolveConstValue(block, operand_src, type_info);
12627 const union_val = val.cast(Value.Payload.Union).?.data;12706 const union_val = val.cast(Value.Payload.Union).?.data;
12628 const tag_ty = type_info_ty.unionTagType().?;12707 const tag_ty = type_info_ty.unionTagType().?;
12629 const tag_index = tag_ty.enumTagFieldIndex(union_val.tag).?;
12630 const target = sema.mod.getTarget();12708 const target = sema.mod.getTarget();
12709 const tag_index = tag_ty.enumTagFieldIndex(union_val.tag, target).?;
12631 switch (@intToEnum(std.builtin.TypeId, tag_index)) {12710 switch (@intToEnum(std.builtin.TypeId, tag_index)) {
12632 .Type => return Air.Inst.Ref.type_type,12711 .Type => return Air.Inst.Ref.type_type,
12633 .Void => return Air.Inst.Ref.void_type,12712 .Void => return Air.Inst.Ref.void_type,
...@@ -12646,7 +12725,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -12646,7 +12725,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
12646 const bits_val = struct_val[1];12725 const bits_val = struct_val[1];
1264712726
12648 const signedness = signedness_val.toEnum(std.builtin.Signedness);12727 const signedness = signedness_val.toEnum(std.builtin.Signedness);
12649 const bits = @intCast(u16, bits_val.toUnsignedInt());12728 const bits = @intCast(u16, bits_val.toUnsignedInt(target));
12650 const ty = switch (signedness) {12729 const ty = switch (signedness) {
12651 .signed => try Type.Tag.int_signed.create(sema.arena, bits),12730 .signed => try Type.Tag.int_signed.create(sema.arena, bits),
12652 .unsigned => try Type.Tag.int_unsigned.create(sema.arena, bits),12731 .unsigned => try Type.Tag.int_unsigned.create(sema.arena, bits),
...@@ -12659,7 +12738,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -12659,7 +12738,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
12659 const len_val = struct_val[0];12738 const len_val = struct_val[0];
12660 const child_val = struct_val[1];12739 const child_val = struct_val[1];
1266112740
12662 const len = len_val.toUnsignedInt();12741 const len = len_val.toUnsignedInt(target);
12663 var buffer: Value.ToTypeBuffer = undefined;12742 var buffer: Value.ToTypeBuffer = undefined;
12664 const child_ty = child_val.toType(&buffer);12743 const child_ty = child_val.toType(&buffer);
1266512744
...@@ -12672,7 +12751,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -12672,7 +12751,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
12672 // bits: comptime_int,12751 // bits: comptime_int,
12673 const bits_val = struct_val[0];12752 const bits_val = struct_val[0];
1267412753
12675 const bits = @intCast(u16, bits_val.toUnsignedInt());12754 const bits = @intCast(u16, bits_val.toUnsignedInt(target));
12676 const ty = switch (bits) {12755 const ty = switch (bits) {
12677 16 => Type.@"f16",12756 16 => Type.@"f16",
12678 32 => Type.@"f32",12757 32 => Type.@"f32",
...@@ -12717,7 +12796,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -12717,7 +12796,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
12717 .size = ptr_size,12796 .size = ptr_size,
12718 .mutable = !is_const_val.toBool(),12797 .mutable = !is_const_val.toBool(),
12719 .@"volatile" = is_volatile_val.toBool(),12798 .@"volatile" = is_volatile_val.toBool(),
12720 .@"align" = @intCast(u16, alignment_val.toUnsignedInt()), // TODO: Validate this value.12799 .@"align" = @intCast(u16, alignment_val.toUnsignedInt(target)), // TODO: Validate this value.
12721 .@"addrspace" = address_space_val.toEnum(std.builtin.AddressSpace),12800 .@"addrspace" = address_space_val.toEnum(std.builtin.AddressSpace),
12722 .pointee_type = try child_ty.copy(sema.arena),12801 .pointee_type = try child_ty.copy(sema.arena),
12723 .@"allowzero" = is_allowzero_val.toBool(),12802 .@"allowzero" = is_allowzero_val.toBool(),
...@@ -12735,7 +12814,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -12735,7 +12814,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
12735 // sentinel: ?*const anyopaque,12814 // sentinel: ?*const anyopaque,
12736 const sentinel_val = struct_val[2];12815 const sentinel_val = struct_val[2];
1273712816
12738 const len = len_val.toUnsignedInt();12817 const len = len_val.toUnsignedInt(target);
12739 var buffer: Value.ToTypeBuffer = undefined;12818 var buffer: Value.ToTypeBuffer = undefined;
12740 const child_ty = try child_val.toType(&buffer).copy(sema.arena);12819 const child_ty = try child_val.toType(&buffer).copy(sema.arena);
12741 const sentinel = if (sentinel_val.castTag(.opt_payload)) |p| blk: {12820 const sentinel = if (sentinel_val.castTag(.opt_payload)) |p| blk: {
...@@ -12746,7 +12825,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -12746,7 +12825,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
12746 break :blk (try sema.pointerDeref(block, src, p.data, ptr_ty)).?;12825 break :blk (try sema.pointerDeref(block, src, p.data, ptr_ty)).?;
12747 } else null;12826 } else null;
1274812827
12749 const ty = try Type.array(sema.arena, len, sentinel, child_ty);12828 const ty = try Type.array(sema.arena, len, sentinel, child_ty, target);
12750 return sema.addType(ty);12829 return sema.addType(ty);
12751 },12830 },
12752 .Optional => {12831 .Optional => {
...@@ -12796,7 +12875,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -12796,7 +12875,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
12796 const name_val = struct_val[0];12875 const name_val = struct_val[0];
1279712876
12798 names.putAssumeCapacityNoClobber(12877 names.putAssumeCapacityNoClobber(
12799 try name_val.toAllocatedBytes(Type.initTag(.const_slice_u8), sema.arena),12878 try name_val.toAllocatedBytes(Type.initTag(.const_slice_u8), sema.arena, target),
12800 {},12879 {},
12801 );12880 );
12802 }12881 }
...@@ -12817,7 +12896,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -12817,7 +12896,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
12817 const is_tuple_val = struct_val[3];12896 const is_tuple_val = struct_val[3];
1281812897
12819 // Decls12898 // Decls
12820 if (decls_val.sliceLen() > 0) {12899 if (decls_val.sliceLen(target) > 0) {
12821 return sema.fail(block, src, "reified structs must have no decls", .{});12900 return sema.fail(block, src, "reified structs must have no decls", .{});
12822 }12901 }
1282312902
...@@ -12847,7 +12926,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -12847,7 +12926,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
12847 }12926 }
1284812927
12849 // Decls12928 // Decls
12850 if (decls_val.sliceLen() > 0) {12929 if (decls_val.sliceLen(target) > 0) {
12851 return sema.fail(block, src, "reified enums must have no decls", .{});12930 return sema.fail(block, src, "reified enums must have no decls", .{});
12852 }12931 }
1285312932
...@@ -12898,11 +12977,12 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -12898,11 +12977,12 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
12898 enum_obj.tag_ty = try tag_type_val.toType(&buffer).copy(new_decl_arena_allocator);12977 enum_obj.tag_ty = try tag_type_val.toType(&buffer).copy(new_decl_arena_allocator);
1289912978
12900 // Fields12979 // Fields
12901 const fields_len = try sema.usizeCast(block, src, fields_val.sliceLen());12980 const fields_len = try sema.usizeCast(block, src, fields_val.sliceLen(target));
12902 if (fields_len > 0) {12981 if (fields_len > 0) {
12903 try enum_obj.fields.ensureTotalCapacity(new_decl_arena_allocator, fields_len);12982 try enum_obj.fields.ensureTotalCapacity(new_decl_arena_allocator, fields_len);
12904 try enum_obj.values.ensureTotalCapacityContext(new_decl_arena_allocator, fields_len, .{12983 try enum_obj.values.ensureTotalCapacityContext(new_decl_arena_allocator, fields_len, .{
12905 .ty = enum_obj.tag_ty,12984 .ty = enum_obj.tag_ty,
12985 .target = target,
12906 });12986 });
1290712987
12908 var i: usize = 0;12988 var i: usize = 0;
...@@ -12918,6 +12998,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -12918,6 +12998,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
12918 const field_name = try name_val.toAllocatedBytes(12998 const field_name = try name_val.toAllocatedBytes(
12919 Type.initTag(.const_slice_u8),12999 Type.initTag(.const_slice_u8),
12920 new_decl_arena_allocator,13000 new_decl_arena_allocator,
13001 target,
12921 );13002 );
1292213003
12923 const gop = enum_obj.fields.getOrPutAssumeCapacity(field_name);13004 const gop = enum_obj.fields.getOrPutAssumeCapacity(field_name);
...@@ -12929,6 +13010,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -12929,6 +13010,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
12929 const copied_tag_val = try value_val.copy(new_decl_arena_allocator);13010 const copied_tag_val = try value_val.copy(new_decl_arena_allocator);
12930 enum_obj.values.putAssumeCapacityNoClobberContext(copied_tag_val, {}, .{13011 enum_obj.values.putAssumeCapacityNoClobberContext(copied_tag_val, {}, .{
12931 .ty = enum_obj.tag_ty,13012 .ty = enum_obj.tag_ty,
13013 .target = target,
12932 });13014 });
12933 }13015 }
12934 }13016 }
...@@ -12942,7 +13024,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -12942,7 +13024,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
12942 const decls_val = struct_val[0];13024 const decls_val = struct_val[0];
1294313025
12944 // Decls13026 // Decls
12945 if (decls_val.sliceLen() > 0) {13027 if (decls_val.sliceLen(target) > 0) {
12946 return sema.fail(block, src, "reified opaque must have no decls", .{});13028 return sema.fail(block, src, "reified opaque must have no decls", .{});
12947 }13029 }
1294813030
...@@ -12993,7 +13075,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -12993,7 +13075,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
12993 const decls_val = struct_val[3];13075 const decls_val = struct_val[3];
1299413076
12995 // Decls13077 // Decls
12996 if (decls_val.sliceLen() > 0) {13078 if (decls_val.sliceLen(target) > 0) {
12997 return sema.fail(block, src, "reified unions must have no decls", .{});13079 return sema.fail(block, src, "reified unions must have no decls", .{});
12998 }13080 }
1299913081
...@@ -13033,7 +13115,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -13033,7 +13115,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
13033 };13115 };
1303413116
13035 // Tag type13117 // Tag type
13036 const fields_len = try sema.usizeCast(block, src, fields_val.sliceLen());13118 const fields_len = try sema.usizeCast(block, src, fields_val.sliceLen(target));
13037 union_obj.tag_ty = if (tag_type_val.optionalValue()) |payload_val| blk: {13119 union_obj.tag_ty = if (tag_type_val.optionalValue()) |payload_val| blk: {
13038 var buffer: Value.ToTypeBuffer = undefined;13120 var buffer: Value.ToTypeBuffer = undefined;
13039 break :blk try payload_val.toType(&buffer).copy(new_decl_arena_allocator);13121 break :blk try payload_val.toType(&buffer).copy(new_decl_arena_allocator);
...@@ -13058,6 +13140,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -13058,6 +13140,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
13058 const field_name = try name_val.toAllocatedBytes(13140 const field_name = try name_val.toAllocatedBytes(
13059 Type.initTag(.const_slice_u8),13141 Type.initTag(.const_slice_u8),
13060 new_decl_arena_allocator,13142 new_decl_arena_allocator,
13143 target,
13061 );13144 );
1306213145
13063 const gop = union_obj.fields.getOrPutAssumeCapacity(field_name);13146 const gop = union_obj.fields.getOrPutAssumeCapacity(field_name);
...@@ -13069,7 +13152,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -13069,7 +13152,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
13069 var buffer: Value.ToTypeBuffer = undefined;13152 var buffer: Value.ToTypeBuffer = undefined;
13070 gop.value_ptr.* = .{13153 gop.value_ptr.* = .{
13071 .ty = try field_type_val.toType(&buffer).copy(new_decl_arena_allocator),13154 .ty = try field_type_val.toType(&buffer).copy(new_decl_arena_allocator),
13072 .abi_align = @intCast(u32, alignment_val.toUnsignedInt()),13155 .abi_align = @intCast(u32, alignment_val.toUnsignedInt(target)),
13073 };13156 };
13074 }13157 }
13075 }13158 }
...@@ -13089,7 +13172,9 @@ fn reifyTuple(...@@ -13089,7 +13172,9 @@ fn reifyTuple(
13089 src: LazySrcLoc,13172 src: LazySrcLoc,
13090 fields_val: Value,13173 fields_val: Value,
13091) CompileError!Air.Inst.Ref {13174) CompileError!Air.Inst.Ref {
13092 const fields_len = try sema.usizeCast(block, src, fields_val.sliceLen());13175 const target = sema.mod.getTarget();
13176
13177 const fields_len = try sema.usizeCast(block, src, fields_val.sliceLen(target));
13093 if (fields_len == 0) return sema.addType(Type.initTag(.empty_struct_literal));13178 if (fields_len == 0) return sema.addType(Type.initTag(.empty_struct_literal));
1309413179
13095 const types = try sema.arena.alloc(Type, fields_len);13180 const types = try sema.arena.alloc(Type, fields_len);
...@@ -13114,6 +13199,7 @@ fn reifyTuple(...@@ -13114,6 +13199,7 @@ fn reifyTuple(
13114 const field_name = try name_val.toAllocatedBytes(13199 const field_name = try name_val.toAllocatedBytes(
13115 Type.initTag(.const_slice_u8),13200 Type.initTag(.const_slice_u8),
13116 sema.arena,13201 sema.arena,
13202 target,
13117 );13203 );
1311813204
13119 const field_index = std.fmt.parseUnsigned(u32, field_name, 10) catch |err| {13205 const field_index = std.fmt.parseUnsigned(u32, field_name, 10) catch |err| {
...@@ -13197,8 +13283,10 @@ fn reifyStruct(...@@ -13197,8 +13283,10 @@ fn reifyStruct(
13197 },13283 },
13198 };13284 };
1319913285
13286 const target = sema.mod.getTarget();
13287
13200 // Fields13288 // Fields
13201 const fields_len = try sema.usizeCast(block, src, fields_val.sliceLen());13289 const fields_len = try sema.usizeCast(block, src, fields_val.sliceLen(target));
13202 try struct_obj.fields.ensureTotalCapacity(new_decl_arena_allocator, fields_len);13290 try struct_obj.fields.ensureTotalCapacity(new_decl_arena_allocator, fields_len);
13203 var i: usize = 0;13291 var i: usize = 0;
13204 while (i < fields_len) : (i += 1) {13292 while (i < fields_len) : (i += 1) {
...@@ -13219,6 +13307,7 @@ fn reifyStruct(...@@ -13219,6 +13307,7 @@ fn reifyStruct(
13219 const field_name = try name_val.toAllocatedBytes(13307 const field_name = try name_val.toAllocatedBytes(
13220 Type.initTag(.const_slice_u8),13308 Type.initTag(.const_slice_u8),
13221 new_decl_arena_allocator,13309 new_decl_arena_allocator,
13310 target,
13222 );13311 );
1322313312
13224 const gop = struct_obj.fields.getOrPutAssumeCapacity(field_name);13313 const gop = struct_obj.fields.getOrPutAssumeCapacity(field_name);
...@@ -13238,7 +13327,7 @@ fn reifyStruct(...@@ -13238,7 +13327,7 @@ fn reifyStruct(
13238 var buffer: Value.ToTypeBuffer = undefined;13327 var buffer: Value.ToTypeBuffer = undefined;
13239 gop.value_ptr.* = .{13328 gop.value_ptr.* = .{
13240 .ty = try field_type_val.toType(&buffer).copy(new_decl_arena_allocator),13329 .ty = try field_type_val.toType(&buffer).copy(new_decl_arena_allocator),
13241 .abi_align = @intCast(u32, alignment_val.toUnsignedInt()),13330 .abi_align = @intCast(u32, alignment_val.toUnsignedInt(target)),
13242 .default_val = default_val,13331 .default_val = default_val,
13243 .is_comptime = is_comptime_val.toBool(),13332 .is_comptime = is_comptime_val.toBool(),
13244 .offset = undefined,13333 .offset = undefined,
...@@ -13257,7 +13346,8 @@ fn zirTypeName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13257,7 +13346,8 @@ fn zirTypeName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13257 var anon_decl = try block.startAnonDecl(LazySrcLoc.unneeded);13346 var anon_decl = try block.startAnonDecl(LazySrcLoc.unneeded);
13258 defer anon_decl.deinit();13347 defer anon_decl.deinit();
1325913348
13260 const bytes = try ty.nameAllocArena(anon_decl.arena());13349 const target = sema.mod.getTarget();
13350 const bytes = try ty.nameAllocArena(anon_decl.arena(), target);
1326113351
13262 const new_decl = try anon_decl.finish(13352 const new_decl = try anon_decl.finish(
13263 try Type.Tag.array_u8_sentinel_0.create(anon_decl.arena(), bytes.len),13353 try Type.Tag.array_u8_sentinel_0.create(anon_decl.arena(), bytes.len),
...@@ -13296,7 +13386,10 @@ fn zirFloatToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -13296,7 +13386,10 @@ fn zirFloatToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
13296 const target = sema.mod.getTarget();13386 const target = sema.mod.getTarget();
13297 const result_val = val.floatToInt(sema.arena, operand_ty, dest_ty, target) catch |err| switch (err) {13387 const result_val = val.floatToInt(sema.arena, operand_ty, dest_ty, target) catch |err| switch (err) {
13298 error.FloatCannotFit => {13388 error.FloatCannotFit => {
13299 return sema.fail(block, operand_src, "integer value {d} cannot be stored in type '{}'", .{ std.math.floor(val.toFloat(f64)), dest_ty });13389 return sema.fail(block, operand_src, "integer value {d} cannot be stored in type '{}'", .{
13390 std.math.floor(val.toFloat(f64)),
13391 dest_ty.fmt(target),
13392 });
13300 },13393 },
13301 else => |e| return e,13394 else => |e| return e,
13302 };13395 };
...@@ -13344,13 +13437,14 @@ fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13344,13 +13437,14 @@ fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13344 try sema.checkPtrType(block, type_src, type_res);13437 try sema.checkPtrType(block, type_src, type_res);
13345 try sema.resolveTypeLayout(block, src, type_res.elemType2());13438 try sema.resolveTypeLayout(block, src, type_res.elemType2());
13346 const ptr_align = type_res.ptrAlignment(sema.mod.getTarget());13439 const ptr_align = type_res.ptrAlignment(sema.mod.getTarget());
13440 const target = sema.mod.getTarget();
1334713441
13348 if (try sema.resolveDefinedValue(block, operand_src, operand_coerced)) |val| {13442 if (try sema.resolveDefinedValue(block, operand_src, operand_coerced)) |val| {
13349 const addr = val.toUnsignedInt();13443 const addr = val.toUnsignedInt(target);
13350 if (!type_res.isAllowzeroPtr() and addr == 0)13444 if (!type_res.isAllowzeroPtr() and addr == 0)
13351 return sema.fail(block, operand_src, "pointer type '{}' does not allow address zero", .{type_res});13445 return sema.fail(block, operand_src, "pointer type '{}' does not allow address zero", .{type_res.fmt(target)});
13352 if (addr != 0 and addr % ptr_align != 0)13446 if (addr != 0 and addr % ptr_align != 0)
13353 return sema.fail(block, operand_src, "pointer type '{}' requires aligned address", .{type_res});13447 return sema.fail(block, operand_src, "pointer type '{}' requires aligned address", .{type_res.fmt(target)});
1335413448
13355 const val_payload = try sema.arena.create(Value.Payload.U64);13449 const val_payload = try sema.arena.create(Value.Payload.U64);
13356 val_payload.* = .{13450 val_payload.* = .{
...@@ -13394,6 +13488,7 @@ fn zirErrSetCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -13394,6 +13488,7 @@ fn zirErrSetCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
13394 const dest_ty = try sema.resolveType(block, dest_ty_src, extra.lhs);13488 const dest_ty = try sema.resolveType(block, dest_ty_src, extra.lhs);
13395 const operand = sema.resolveInst(extra.rhs);13489 const operand = sema.resolveInst(extra.rhs);
13396 const operand_ty = sema.typeOf(operand);13490 const operand_ty = sema.typeOf(operand);
13491 const target = sema.mod.getTarget();
13397 try sema.checkErrorSetType(block, dest_ty_src, dest_ty);13492 try sema.checkErrorSetType(block, dest_ty_src, dest_ty);
13398 try sema.checkErrorSetType(block, operand_src, operand_ty);13493 try sema.checkErrorSetType(block, operand_src, operand_ty);
1339913494
...@@ -13407,7 +13502,7 @@ fn zirErrSetCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -13407,7 +13502,7 @@ fn zirErrSetCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
13407 block,13502 block,
13408 src,13503 src,
13409 "error.{s} not a member of error set '{}'",13504 "error.{s} not a member of error set '{}'",
13410 .{ error_name, dest_ty },13505 .{ error_name, dest_ty.fmt(target) },
13411 );13506 );
13412 }13507 }
13413 }13508 }
...@@ -13502,7 +13597,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13502,7 +13597,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1350213597
13503 if (operand_info.signedness != dest_info.signedness) {13598 if (operand_info.signedness != dest_info.signedness) {
13504 return sema.fail(block, operand_src, "expected {s} integer type, found '{}'", .{13599 return sema.fail(block, operand_src, "expected {s} integer type, found '{}'", .{
13505 @tagName(dest_info.signedness), operand_ty,13600 @tagName(dest_info.signedness), operand_ty.fmt(target),
13506 });13601 });
13507 }13602 }
13508 if (operand_info.bits < dest_info.bits) {13603 if (operand_info.bits < dest_info.bits) {
...@@ -13511,7 +13606,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13511,7 +13606,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13511 block,13606 block,
13512 src,13607 src,
13513 "destination type '{}' has more bits than source type '{}'",13608 "destination type '{}' has more bits than source type '{}'",
13514 .{ dest_ty, operand_ty },13609 .{ dest_ty.fmt(target), operand_ty.fmt(target) },
13515 );13610 );
13516 errdefer msg.destroy(sema.gpa);13611 errdefer msg.destroy(sema.gpa);
13517 try sema.errNote(block, dest_ty_src, msg, "destination type has {d} bits", .{13612 try sema.errNote(block, dest_ty_src, msg, "destination type has {d} bits", .{
...@@ -13531,14 +13626,14 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13531,14 +13626,14 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13531 if (!is_vector) {13626 if (!is_vector) {
13532 return sema.addConstant(13627 return sema.addConstant(
13533 dest_ty,13628 dest_ty,
13534 try val.intTrunc(operand_ty, sema.arena, dest_info.signedness, dest_info.bits),13629 try val.intTrunc(operand_ty, sema.arena, dest_info.signedness, dest_info.bits, target),
13535 );13630 );
13536 }13631 }
13537 var elem_buf: Value.ElemValueBuffer = undefined;13632 var elem_buf: Value.ElemValueBuffer = undefined;
13538 const elems = try sema.arena.alloc(Value, operand_ty.vectorLen());13633 const elems = try sema.arena.alloc(Value, operand_ty.vectorLen());
13539 for (elems) |*elem, i| {13634 for (elems) |*elem, i| {
13540 const elem_val = val.elemValueBuffer(i, &elem_buf);13635 const elem_val = val.elemValueBuffer(i, &elem_buf);
13541 elem.* = try elem_val.intTrunc(operand_scalar_ty, sema.arena, dest_info.signedness, dest_info.bits);13636 elem.* = try elem_val.intTrunc(operand_scalar_ty, sema.arena, dest_info.signedness, dest_info.bits, target);
13542 }13637 }
13543 return sema.addConstant(13638 return sema.addConstant(
13544 dest_ty,13639 dest_ty,
...@@ -13653,7 +13748,7 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13653,7 +13748,7 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13653 block,13748 block,
13654 ty_src,13749 ty_src,
13655 "@byteSwap requires the number of bits to be evenly divisible by 8, but {} has {} bits",13750 "@byteSwap requires the number of bits to be evenly divisible by 8, but {} has {} bits",
13656 .{ scalar_ty, bits },13751 .{ scalar_ty.fmt(target), bits },
13657 );13752 );
13658 }13753 }
1365913754
...@@ -13765,6 +13860,7 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6...@@ -13765,6 +13860,7 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6
1376513860
13766 const ty = try sema.resolveType(block, lhs_src, extra.lhs);13861 const ty = try sema.resolveType(block, lhs_src, extra.lhs);
13767 const field_name = try sema.resolveConstString(block, rhs_src, extra.rhs);13862 const field_name = try sema.resolveConstString(block, rhs_src, extra.rhs);
13863 const target = sema.mod.getTarget();
1376813864
13769 try sema.resolveTypeLayout(block, lhs_src, ty);13865 try sema.resolveTypeLayout(block, lhs_src, ty);
13770 if (ty.tag() != .@"struct") {13866 if (ty.tag() != .@"struct") {
...@@ -13772,7 +13868,7 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6...@@ -13772,7 +13868,7 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6
13772 block,13868 block,
13773 lhs_src,13869 lhs_src,
13774 "expected struct type, found '{}'",13870 "expected struct type, found '{}'",
13775 .{ty},13871 .{ty.fmt(target)},
13776 );13872 );
13777 }13873 }
1377813874
...@@ -13782,11 +13878,10 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6...@@ -13782,11 +13878,10 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6
13782 block,13878 block,
13783 rhs_src,13879 rhs_src,
13784 "struct '{}' has no field '{s}'",13880 "struct '{}' has no field '{s}'",
13785 .{ ty, field_name },13881 .{ ty.fmt(target), field_name },
13786 );13882 );
13787 };13883 };
1378813884
13789 const target = sema.mod.getTarget();
13790 switch (ty.containerLayout()) {13885 switch (ty.containerLayout()) {
13791 .Packed => {13886 .Packed => {
13792 var bit_sum: u64 = 0;13887 var bit_sum: u64 = 0;
...@@ -13809,18 +13904,20 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6...@@ -13809,18 +13904,20 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6
13809}13904}
1381013905
13811fn checkNamespaceType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!void {13906fn checkNamespaceType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!void {
13907 const target = sema.mod.getTarget();
13812 switch (ty.zigTypeTag()) {13908 switch (ty.zigTypeTag()) {
13813 .Struct, .Enum, .Union, .Opaque => return,13909 .Struct, .Enum, .Union, .Opaque => return,
13814 else => return sema.fail(block, src, "expected struct, enum, union, or opaque; found '{}'", .{ty}),13910 else => return sema.fail(block, src, "expected struct, enum, union, or opaque; found '{}'", .{ty.fmt(target)}),
13815 }13911 }
13816}13912}
1381713913
13818/// Returns `true` if the type was a comptime_int.13914/// Returns `true` if the type was a comptime_int.
13819fn checkIntType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!bool {13915fn checkIntType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!bool {
13916 const target = sema.mod.getTarget();
13820 switch (try ty.zigTypeTagOrPoison()) {13917 switch (try ty.zigTypeTagOrPoison()) {
13821 .ComptimeInt => return true,13918 .ComptimeInt => return true,
13822 .Int => return false,13919 .Int => return false,
13823 else => return sema.fail(block, src, "expected integer type, found '{}'", .{ty}),13920 else => return sema.fail(block, src, "expected integer type, found '{}'", .{ty.fmt(target)}),
13824 }13921 }
13825}13922}
1382613923
...@@ -13830,6 +13927,7 @@ fn checkPtrOperand(...@@ -13830,6 +13927,7 @@ fn checkPtrOperand(
13830 ty_src: LazySrcLoc,13927 ty_src: LazySrcLoc,
13831 ty: Type,13928 ty: Type,
13832) CompileError!void {13929) CompileError!void {
13930 const target = sema.mod.getTarget();
13833 switch (ty.zigTypeTag()) {13931 switch (ty.zigTypeTag()) {
13834 .Pointer => return,13932 .Pointer => return,
13835 .Fn => {13933 .Fn => {
...@@ -13838,7 +13936,7 @@ fn checkPtrOperand(...@@ -13838,7 +13936,7 @@ fn checkPtrOperand(
13838 block,13936 block,
13839 ty_src,13937 ty_src,
13840 "expected pointer, found {}",13938 "expected pointer, found {}",
13841 .{ty},13939 .{ty.fmt(target)},
13842 );13940 );
13843 errdefer msg.destroy(sema.gpa);13941 errdefer msg.destroy(sema.gpa);
1384413942
...@@ -13851,7 +13949,7 @@ fn checkPtrOperand(...@@ -13851,7 +13949,7 @@ fn checkPtrOperand(
13851 .Optional => if (ty.isPtrLikeOptional()) return,13949 .Optional => if (ty.isPtrLikeOptional()) return,
13852 else => {},13950 else => {},
13853 }13951 }
13854 return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{ty});13952 return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{ty.fmt(target)});
13855}13953}
1385613954
13857fn checkPtrType(13955fn checkPtrType(
...@@ -13860,6 +13958,7 @@ fn checkPtrType(...@@ -13860,6 +13958,7 @@ fn checkPtrType(
13860 ty_src: LazySrcLoc,13958 ty_src: LazySrcLoc,
13861 ty: Type,13959 ty: Type,
13862) CompileError!void {13960) CompileError!void {
13961 const target = sema.mod.getTarget();
13863 switch (ty.zigTypeTag()) {13962 switch (ty.zigTypeTag()) {
13864 .Pointer => return,13963 .Pointer => return,
13865 .Fn => {13964 .Fn => {
...@@ -13868,7 +13967,7 @@ fn checkPtrType(...@@ -13868,7 +13967,7 @@ fn checkPtrType(
13868 block,13967 block,
13869 ty_src,13968 ty_src,
13870 "expected pointer type, found '{}'",13969 "expected pointer type, found '{}'",
13871 .{ty},13970 .{ty.fmt(target)},
13872 );13971 );
13873 errdefer msg.destroy(sema.gpa);13972 errdefer msg.destroy(sema.gpa);
1387413973
...@@ -13881,7 +13980,7 @@ fn checkPtrType(...@@ -13881,7 +13980,7 @@ fn checkPtrType(
13881 .Optional => if (ty.isPtrLikeOptional()) return,13980 .Optional => if (ty.isPtrLikeOptional()) return,
13882 else => {},13981 else => {},
13883 }13982 }
13884 return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{ty});13983 return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{ty.fmt(target)});
13885}13984}
1388613985
13887fn checkVectorElemType(13986fn checkVectorElemType(
...@@ -13894,7 +13993,8 @@ fn checkVectorElemType(...@@ -13894,7 +13993,8 @@ fn checkVectorElemType(
13894 .Int, .Float, .Bool => return,13993 .Int, .Float, .Bool => return,
13895 else => if (ty.isPtrAtRuntime()) return,13994 else => if (ty.isPtrAtRuntime()) return,
13896 }13995 }
13897 return sema.fail(block, ty_src, "expected integer, float, bool, or pointer for the vector element type; found '{}'", .{ty});13996 const target = sema.mod.getTarget();
13997 return sema.fail(block, ty_src, "expected integer, float, bool, or pointer for the vector element type; found '{}'", .{ty.fmt(target)});
13898}13998}
1389913999
13900fn checkFloatType(14000fn checkFloatType(
...@@ -13903,9 +14003,10 @@ fn checkFloatType(...@@ -13903,9 +14003,10 @@ fn checkFloatType(
13903 ty_src: LazySrcLoc,14003 ty_src: LazySrcLoc,
13904 ty: Type,14004 ty: Type,
13905) CompileError!void {14005) CompileError!void {
14006 const target = sema.mod.getTarget();
13906 switch (ty.zigTypeTag()) {14007 switch (ty.zigTypeTag()) {
13907 .ComptimeInt, .ComptimeFloat, .Float => {},14008 .ComptimeInt, .ComptimeFloat, .Float => {},
13908 else => return sema.fail(block, ty_src, "expected float type, found '{}'", .{ty}),14009 else => return sema.fail(block, ty_src, "expected float type, found '{}'", .{ty.fmt(target)}),
13909 }14010 }
13910}14011}
1391114012
...@@ -13915,13 +14016,14 @@ fn checkNumericType(...@@ -13915,13 +14016,14 @@ fn checkNumericType(
13915 ty_src: LazySrcLoc,14016 ty_src: LazySrcLoc,
13916 ty: Type,14017 ty: Type,
13917) CompileError!void {14018) CompileError!void {
14019 const target = sema.mod.getTarget();
13918 switch (ty.zigTypeTag()) {14020 switch (ty.zigTypeTag()) {
13919 .ComptimeFloat, .Float, .ComptimeInt, .Int => {},14021 .ComptimeFloat, .Float, .ComptimeInt, .Int => {},
13920 .Vector => switch (ty.childType().zigTypeTag()) {14022 .Vector => switch (ty.childType().zigTypeTag()) {
13921 .ComptimeFloat, .Float, .ComptimeInt, .Int => {},14023 .ComptimeFloat, .Float, .ComptimeInt, .Int => {},
13922 else => |t| return sema.fail(block, ty_src, "expected number, found '{}'", .{t}),14024 else => |t| return sema.fail(block, ty_src, "expected number, found '{}'", .{t}),
13923 },14025 },
13924 else => return sema.fail(block, ty_src, "expected number, found '{}'", .{ty}),14026 else => return sema.fail(block, ty_src, "expected number, found '{}'", .{ty.fmt(target)}),
13925 }14027 }
13926}14028}
1392714029
...@@ -13957,7 +14059,7 @@ fn checkAtomicOperandType(...@@ -13957,7 +14059,7 @@ fn checkAtomicOperandType(
13957 block,14059 block,
13958 ty_src,14060 ty_src,
13959 "expected bool, integer, float, enum, or pointer type; found {}",14061 "expected bool, integer, float, enum, or pointer type; found {}",
13960 .{ty},14062 .{ty.fmt(target)},
13961 );14063 );
13962 },14064 },
13963 };14065 };
...@@ -14021,6 +14123,7 @@ fn checkIntOrVector(...@@ -14021,6 +14123,7 @@ fn checkIntOrVector(
14021 operand_src: LazySrcLoc,14123 operand_src: LazySrcLoc,
14022) CompileError!Type {14124) CompileError!Type {
14023 const operand_ty = sema.typeOf(operand);14125 const operand_ty = sema.typeOf(operand);
14126 const target = sema.mod.getTarget();
14024 switch (try operand_ty.zigTypeTagOrPoison()) {14127 switch (try operand_ty.zigTypeTagOrPoison()) {
14025 .Int => return operand_ty,14128 .Int => return operand_ty,
14026 .Vector => {14129 .Vector => {
...@@ -14028,12 +14131,12 @@ fn checkIntOrVector(...@@ -14028,12 +14131,12 @@ fn checkIntOrVector(
14028 switch (try elem_ty.zigTypeTagOrPoison()) {14131 switch (try elem_ty.zigTypeTagOrPoison()) {
14029 .Int => return elem_ty,14132 .Int => return elem_ty,
14030 else => return sema.fail(block, operand_src, "expected vector of integers; found vector of '{}'", .{14133 else => return sema.fail(block, operand_src, "expected vector of integers; found vector of '{}'", .{
14031 elem_ty,14134 elem_ty.fmt(target),
14032 }),14135 }),
14033 }14136 }
14034 },14137 },
14035 else => return sema.fail(block, operand_src, "expected integer or vector, found '{}'", .{14138 else => return sema.fail(block, operand_src, "expected integer or vector, found '{}'", .{
14036 operand_ty,14139 operand_ty.fmt(target),
14037 }),14140 }),
14038 }14141 }
14039}14142}
...@@ -14045,6 +14148,7 @@ fn checkIntOrVectorAllowComptime(...@@ -14045,6 +14148,7 @@ fn checkIntOrVectorAllowComptime(
14045 operand_src: LazySrcLoc,14148 operand_src: LazySrcLoc,
14046) CompileError!Type {14149) CompileError!Type {
14047 const operand_ty = sema.typeOf(operand);14150 const operand_ty = sema.typeOf(operand);
14151 const target = sema.mod.getTarget();
14048 switch (try operand_ty.zigTypeTagOrPoison()) {14152 switch (try operand_ty.zigTypeTagOrPoison()) {
14049 .Int, .ComptimeInt => return operand_ty,14153 .Int, .ComptimeInt => return operand_ty,
14050 .Vector => {14154 .Vector => {
...@@ -14052,20 +14156,21 @@ fn checkIntOrVectorAllowComptime(...@@ -14052,20 +14156,21 @@ fn checkIntOrVectorAllowComptime(
14052 switch (try elem_ty.zigTypeTagOrPoison()) {14156 switch (try elem_ty.zigTypeTagOrPoison()) {
14053 .Int, .ComptimeInt => return elem_ty,14157 .Int, .ComptimeInt => return elem_ty,
14054 else => return sema.fail(block, operand_src, "expected vector of integers; found vector of '{}'", .{14158 else => return sema.fail(block, operand_src, "expected vector of integers; found vector of '{}'", .{
14055 elem_ty,14159 elem_ty.fmt(target),
14056 }),14160 }),
14057 }14161 }
14058 },14162 },
14059 else => return sema.fail(block, operand_src, "expected integer or vector, found '{}'", .{14163 else => return sema.fail(block, operand_src, "expected integer or vector, found '{}'", .{
14060 operand_ty,14164 operand_ty.fmt(target),
14061 }),14165 }),
14062 }14166 }
14063}14167}
1406414168
14065fn checkErrorSetType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!void {14169fn checkErrorSetType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!void {
14170 const target = sema.mod.getTarget();
14066 switch (ty.zigTypeTag()) {14171 switch (ty.zigTypeTag()) {
14067 .ErrorSet => return,14172 .ErrorSet => return,
14068 else => return sema.fail(block, src, "expected error set type, found '{}'", .{ty}),14173 else => return sema.fail(block, src, "expected error set type, found '{}'", .{ty.fmt(target)}),
14069 }14174 }
14070}14175}
1407114176
...@@ -14138,9 +14243,10 @@ fn checkVectorizableBinaryOperands(...@@ -14138,9 +14243,10 @@ fn checkVectorizableBinaryOperands(
14138 return sema.failWithOwnedErrorMsg(block, msg);14243 return sema.failWithOwnedErrorMsg(block, msg);
14139 }14244 }
14140 } else if (lhs_zig_ty_tag == .Vector or rhs_zig_ty_tag == .Vector) {14245 } else if (lhs_zig_ty_tag == .Vector or rhs_zig_ty_tag == .Vector) {
14246 const target = sema.mod.getTarget();
14141 const msg = msg: {14247 const msg = msg: {
14142 const msg = try sema.errMsg(block, src, "mixed scalar and vector operands: {} and {}", .{14248 const msg = try sema.errMsg(block, src, "mixed scalar and vector operands: {} and {}", .{
14143 lhs_ty, rhs_ty,14249 lhs_ty.fmt(target), rhs_ty.fmt(target),
14144 });14250 });
14145 errdefer msg.destroy(sema.gpa);14251 errdefer msg.destroy(sema.gpa);
14146 if (lhs_zig_ty_tag == .Vector) {14252 if (lhs_zig_ty_tag == .Vector) {
...@@ -14179,8 +14285,9 @@ fn resolveExportOptions(...@@ -14179,8 +14285,9 @@ fn resolveExportOptions(
14179 return sema.fail(block, src, "TODO: implement exporting with linksection", .{});14285 return sema.fail(block, src, "TODO: implement exporting with linksection", .{});
14180 }14286 }
14181 const name_ty = Type.initTag(.const_slice_u8);14287 const name_ty = Type.initTag(.const_slice_u8);
14288 const target = sema.mod.getTarget();
14182 return std.builtin.ExportOptions{14289 return std.builtin.ExportOptions{
14183 .name = try name_val.toAllocatedBytes(name_ty, sema.arena),14290 .name = try name_val.toAllocatedBytes(name_ty, sema.arena, target),
14184 .linkage = linkage_val.toEnum(std.builtin.GlobalLinkage),14291 .linkage = linkage_val.toEnum(std.builtin.GlobalLinkage),
14185 .section = null, // TODO14292 .section = null, // TODO
14186 };14293 };
...@@ -14239,12 +14346,13 @@ fn zirCmpxchg(...@@ -14239,12 +14346,13 @@ fn zirCmpxchg(
14239 const ptr_ty = sema.typeOf(ptr);14346 const ptr_ty = sema.typeOf(ptr);
14240 const elem_ty = ptr_ty.elemType();14347 const elem_ty = ptr_ty.elemType();
14241 try sema.checkAtomicOperandType(block, elem_ty_src, elem_ty);14348 try sema.checkAtomicOperandType(block, elem_ty_src, elem_ty);
14349 const target = sema.mod.getTarget();
14242 if (elem_ty.zigTypeTag() == .Float) {14350 if (elem_ty.zigTypeTag() == .Float) {
14243 return sema.fail(14351 return sema.fail(
14244 block,14352 block,
14245 elem_ty_src,14353 elem_ty_src,
14246 "expected bool, integer, enum, or pointer type; found '{}'",14354 "expected bool, integer, enum, or pointer type; found '{}'",
14247 .{elem_ty},14355 .{elem_ty.fmt(target)},
14248 );14356 );
14249 }14357 }
14250 const expected_value = try sema.coerce(block, elem_ty, sema.resolveInst(extra.expected_value), expected_src);14358 const expected_value = try sema.coerce(block, elem_ty, sema.resolveInst(extra.expected_value), expected_src);
...@@ -14281,7 +14389,7 @@ fn zirCmpxchg(...@@ -14281,7 +14389,7 @@ fn zirCmpxchg(
14281 return sema.addConstUndef(result_ty);14389 return sema.addConstUndef(result_ty);
14282 }14390 }
14283 const stored_val = (try sema.pointerDeref(block, ptr_src, ptr_val, ptr_ty)) orelse break :rs ptr_src;14391 const stored_val = (try sema.pointerDeref(block, ptr_src, ptr_val, ptr_ty)) orelse break :rs ptr_src;
14284 const result_val = if (stored_val.eql(expected_val, elem_ty)) blk: {14392 const result_val = if (stored_val.eql(expected_val, elem_ty, target)) blk: {
14285 try sema.storePtr(block, src, ptr, new_value);14393 try sema.storePtr(block, src, ptr, new_value);
14286 break :blk Value.@"null";14394 break :blk Value.@"null";
14287 } else try Value.Tag.opt_payload.create(sema.arena, stored_val);14395 } else try Value.Tag.opt_payload.create(sema.arena, stored_val);
...@@ -14343,9 +14451,10 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -14343,9 +14451,10 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
14343 const operation = try sema.resolveBuiltinEnum(block, op_src, extra.lhs, "ReduceOp");14451 const operation = try sema.resolveBuiltinEnum(block, op_src, extra.lhs, "ReduceOp");
14344 const operand = sema.resolveInst(extra.rhs);14452 const operand = sema.resolveInst(extra.rhs);
14345 const operand_ty = sema.typeOf(operand);14453 const operand_ty = sema.typeOf(operand);
14454 const target = sema.mod.getTarget();
1434614455
14347 if (operand_ty.zigTypeTag() != .Vector) {14456 if (operand_ty.zigTypeTag() != .Vector) {
14348 return sema.fail(block, operand_src, "expected vector, found {}", .{operand_ty});14457 return sema.fail(block, operand_src, "expected vector, found {}", .{operand_ty.fmt(target)});
14349 }14458 }
1435014459
14351 const scalar_ty = operand_ty.childType();14460 const scalar_ty = operand_ty.childType();
...@@ -14355,13 +14464,13 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -14355,13 +14464,13 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
14355 .And, .Or, .Xor => switch (scalar_ty.zigTypeTag()) {14464 .And, .Or, .Xor => switch (scalar_ty.zigTypeTag()) {
14356 .Int, .Bool => {},14465 .Int, .Bool => {},
14357 else => return sema.fail(block, operand_src, "@reduce operation '{s}' requires integer or boolean operand; found {}", .{14466 else => return sema.fail(block, operand_src, "@reduce operation '{s}' requires integer or boolean operand; found {}", .{
14358 @tagName(operation), operand_ty,14467 @tagName(operation), operand_ty.fmt(target),
14359 }),14468 }),
14360 },14469 },
14361 .Min, .Max, .Add, .Mul => switch (scalar_ty.zigTypeTag()) {14470 .Min, .Max, .Add, .Mul => switch (scalar_ty.zigTypeTag()) {
14362 .Int, .Float => {},14471 .Int, .Float => {},
14363 else => return sema.fail(block, operand_src, "@reduce operation '{s}' requires integer or float operand; found {}", .{14472 else => return sema.fail(block, operand_src, "@reduce operation '{s}' requires integer or float operand; found {}", .{
14364 @tagName(operation), operand_ty,14473 @tagName(operation), operand_ty.fmt(target),
14365 }),14474 }),
14366 },14475 },
14367 }14476 }
...@@ -14376,18 +14485,17 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -14376,18 +14485,17 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
14376 if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |operand_val| {14485 if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |operand_val| {
14377 if (operand_val.isUndef()) return sema.addConstUndef(scalar_ty);14486 if (operand_val.isUndef()) return sema.addConstUndef(scalar_ty);
1437814487
14379 const target = sema.mod.getTarget();
14380 var accum: Value = try operand_val.elemValue(sema.arena, 0);14488 var accum: Value = try operand_val.elemValue(sema.arena, 0);
14381 var elem_buf: Value.ElemValueBuffer = undefined;14489 var elem_buf: Value.ElemValueBuffer = undefined;
14382 var i: u32 = 1;14490 var i: u32 = 1;
14383 while (i < vec_len) : (i += 1) {14491 while (i < vec_len) : (i += 1) {
14384 const elem_val = operand_val.elemValueBuffer(i, &elem_buf);14492 const elem_val = operand_val.elemValueBuffer(i, &elem_buf);
14385 switch (operation) {14493 switch (operation) {
14386 .And => accum = try accum.bitwiseAnd(elem_val, scalar_ty, sema.arena),14494 .And => accum = try accum.bitwiseAnd(elem_val, scalar_ty, sema.arena, target),
14387 .Or => accum = try accum.bitwiseOr(elem_val, scalar_ty, sema.arena),14495 .Or => accum = try accum.bitwiseOr(elem_val, scalar_ty, sema.arena, target),
14388 .Xor => accum = try accum.bitwiseXor(elem_val, scalar_ty, sema.arena),14496 .Xor => accum = try accum.bitwiseXor(elem_val, scalar_ty, sema.arena, target),
14389 .Min => accum = accum.numberMin(elem_val),14497 .Min => accum = accum.numberMin(elem_val, target),
14390 .Max => accum = accum.numberMax(elem_val),14498 .Max => accum = accum.numberMax(elem_val, target),
14391 .Add => accum = try accum.numberAddWrap(elem_val, scalar_ty, sema.arena, target),14499 .Add => accum = try accum.numberAddWrap(elem_val, scalar_ty, sema.arena, target),
14392 .Mul => accum = try accum.numberMulWrap(elem_val, scalar_ty, sema.arena, target),14500 .Mul => accum = try accum.numberMulWrap(elem_val, scalar_ty, sema.arena, target),
14393 }14501 }
...@@ -14417,10 +14525,11 @@ fn zirShuffle(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -14417,10 +14525,11 @@ fn zirShuffle(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
14417 var b = sema.resolveInst(extra.b);14525 var b = sema.resolveInst(extra.b);
14418 var mask = sema.resolveInst(extra.mask);14526 var mask = sema.resolveInst(extra.mask);
14419 var mask_ty = sema.typeOf(mask);14527 var mask_ty = sema.typeOf(mask);
14528 const target = sema.mod.getTarget();
1442014529
14421 const mask_len = switch (sema.typeOf(mask).zigTypeTag()) {14530 const mask_len = switch (sema.typeOf(mask).zigTypeTag()) {
14422 .Array, .Vector => sema.typeOf(mask).arrayLen(),14531 .Array, .Vector => sema.typeOf(mask).arrayLen(),
14423 else => return sema.fail(block, mask_src, "expected vector or array, found {}", .{sema.typeOf(mask)}),14532 else => return sema.fail(block, mask_src, "expected vector or array, found {}", .{sema.typeOf(mask).fmt(target)}),
14424 };14533 };
14425 mask_ty = try Type.Tag.vector.create(sema.arena, .{14534 mask_ty = try Type.Tag.vector.create(sema.arena, .{
14426 .len = mask_len,14535 .len = mask_len,
...@@ -14452,20 +14561,21 @@ fn analyzeShuffle(...@@ -14452,20 +14561,21 @@ fn analyzeShuffle(
14452 .elem_type = elem_ty,14561 .elem_type = elem_ty,
14453 });14562 });
1445414563
14564 const target = sema.mod.getTarget();
14455 var maybe_a_len = switch (sema.typeOf(a).zigTypeTag()) {14565 var maybe_a_len = switch (sema.typeOf(a).zigTypeTag()) {
14456 .Array, .Vector => sema.typeOf(a).arrayLen(),14566 .Array, .Vector => sema.typeOf(a).arrayLen(),
14457 .Undefined => null,14567 .Undefined => null,
14458 else => return sema.fail(block, a_src, "expected vector or array with element type {}, found {}", .{14568 else => return sema.fail(block, a_src, "expected vector or array with element type {}, found {}", .{
14459 elem_ty,14569 elem_ty.fmt(target),
14460 sema.typeOf(a),14570 sema.typeOf(a).fmt(target),
14461 }),14571 }),
14462 };14572 };
14463 var maybe_b_len = switch (sema.typeOf(b).zigTypeTag()) {14573 var maybe_b_len = switch (sema.typeOf(b).zigTypeTag()) {
14464 .Array, .Vector => sema.typeOf(b).arrayLen(),14574 .Array, .Vector => sema.typeOf(b).arrayLen(),
14465 .Undefined => null,14575 .Undefined => null,
14466 else => return sema.fail(block, b_src, "expected vector or array with element type {}, found {}", .{14576 else => return sema.fail(block, b_src, "expected vector or array with element type {}, found {}", .{
14467 elem_ty,14577 elem_ty.fmt(target),
14468 sema.typeOf(b),14578 sema.typeOf(b).fmt(target),
14469 }),14579 }),
14470 };14580 };
14471 if (maybe_a_len == null and maybe_b_len == null) {14581 if (maybe_a_len == null and maybe_b_len == null) {
...@@ -14513,7 +14623,7 @@ fn analyzeShuffle(...@@ -14513,7 +14623,7 @@ fn analyzeShuffle(
1451314623
14514 try sema.errNote(block, operand_info[chosen][1], msg, "selected index {d} out of bounds of {}", .{14624 try sema.errNote(block, operand_info[chosen][1], msg, "selected index {d} out of bounds of {}", .{
14515 unsigned,14625 unsigned,
14516 operand_info[chosen][2],14626 operand_info[chosen][2].fmt(target),
14517 });14627 });
1451814628
14519 if (chosen == 1) {14629 if (chosen == 1) {
...@@ -14704,12 +14814,12 @@ fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -14704,12 +14814,12 @@ fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
14704 .Xchg => operand_val,14814 .Xchg => operand_val,
14705 .Add => try stored_val.numberAddWrap(operand_val, operand_ty, sema.arena, target),14815 .Add => try stored_val.numberAddWrap(operand_val, operand_ty, sema.arena, target),
14706 .Sub => try stored_val.numberSubWrap(operand_val, operand_ty, sema.arena, target),14816 .Sub => try stored_val.numberSubWrap(operand_val, operand_ty, sema.arena, target),
14707 .And => try stored_val.bitwiseAnd (operand_val, operand_ty, sema.arena),14817 .And => try stored_val.bitwiseAnd (operand_val, operand_ty, sema.arena, target),
14708 .Nand => try stored_val.bitwiseNand (operand_val, operand_ty, sema.arena, target),14818 .Nand => try stored_val.bitwiseNand (operand_val, operand_ty, sema.arena, target),
14709 .Or => try stored_val.bitwiseOr (operand_val, operand_ty, sema.arena),14819 .Or => try stored_val.bitwiseOr (operand_val, operand_ty, sema.arena, target),
14710 .Xor => try stored_val.bitwiseXor (operand_val, operand_ty, sema.arena),14820 .Xor => try stored_val.bitwiseXor (operand_val, operand_ty, sema.arena, target),
14711 .Max => stored_val.numberMax (operand_val),14821 .Max => stored_val.numberMax (operand_val, target),
14712 .Min => stored_val.numberMin (operand_val),14822 .Min => stored_val.numberMin (operand_val, target),
14713 // zig fmt: on14823 // zig fmt: on
14714 };14824 };
14715 try sema.storePtrVal(block, src, ptr_val, new_val, operand_ty);14825 try sema.storePtrVal(block, src, ptr_val, new_val, operand_ty);
...@@ -14788,7 +14898,7 @@ fn zirMulAdd(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -14788,7 +14898,7 @@ fn zirMulAdd(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1478814898
14789 switch (ty.zigTypeTag()) {14899 switch (ty.zigTypeTag()) {
14790 .ComptimeFloat, .Float, .Vector => {},14900 .ComptimeFloat, .Float, .Vector => {},
14791 else => return sema.fail(block, src, "expected vector of floats or float type, found '{}'", .{ty}),14901 else => return sema.fail(block, src, "expected vector of floats or float type, found '{}'", .{ty.fmt(target)}),
14792 }14902 }
1479314903
14794 const runtime_src = if (maybe_mulend1) |mulend1_val| rs: {14904 const runtime_src = if (maybe_mulend1) |mulend1_val| rs: {
...@@ -14814,7 +14924,7 @@ fn zirMulAdd(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -14814,7 +14924,7 @@ fn zirMulAdd(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
14814 const scalar_ty = ty.scalarType();14924 const scalar_ty = ty.scalarType();
14815 switch (scalar_ty.zigTypeTag()) {14925 switch (scalar_ty.zigTypeTag()) {
14816 .ComptimeFloat, .Float => {},14926 .ComptimeFloat, .Float => {},
14817 else => return sema.fail(block, src, "expected vector of floats, found vector of '{}'", .{scalar_ty}),14927 else => return sema.fail(block, src, "expected vector of floats, found vector of '{}'", .{scalar_ty.fmt(target)}),
14818 }14928 }
1481914929
14820 const vec_len = ty.vectorLen();14930 const vec_len = ty.vectorLen();
...@@ -14906,9 +15016,10 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -14906,9 +15016,10 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
14906 break :modifier modifier_val.toEnum(std.builtin.CallOptions.Modifier);15016 break :modifier modifier_val.toEnum(std.builtin.CallOptions.Modifier);
14907 };15017 };
1490815018
15019 const target = sema.mod.getTarget();
14909 const args_ty = sema.typeOf(args);15020 const args_ty = sema.typeOf(args);
14910 if (!args_ty.isTuple() and args_ty.tag() != .empty_struct_literal) {15021 if (!args_ty.isTuple() and args_ty.tag() != .empty_struct_literal) {
14911 return sema.fail(block, args_src, "expected a tuple, found {}", .{args_ty});15022 return sema.fail(block, args_src, "expected a tuple, found {}", .{args_ty.fmt(target)});
14912 }15023 }
1491315024
14914 var resolved_args: []Air.Inst.Ref = undefined;15025 var resolved_args: []Air.Inst.Ref = undefined;
...@@ -14945,9 +15056,10 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -14945,9 +15056,10 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
14945 const field_name = try sema.resolveConstString(block, name_src, extra.field_name);15056 const field_name = try sema.resolveConstString(block, name_src, extra.field_name);
14946 const field_ptr = sema.resolveInst(extra.field_ptr);15057 const field_ptr = sema.resolveInst(extra.field_ptr);
14947 const field_ptr_ty = sema.typeOf(field_ptr);15058 const field_ptr_ty = sema.typeOf(field_ptr);
15059 const target = sema.mod.getTarget();
1494815060
14949 if (struct_ty.zigTypeTag() != .Struct) {15061 if (struct_ty.zigTypeTag() != .Struct) {
14950 return sema.fail(block, ty_src, "expected struct type, found '{}'", .{struct_ty});15062 return sema.fail(block, ty_src, "expected struct type, found '{}'", .{struct_ty.fmt(target)});
14951 }15063 }
14952 try sema.resolveTypeLayout(block, ty_src, struct_ty);15064 try sema.resolveTypeLayout(block, ty_src, struct_ty);
1495315065
...@@ -14956,7 +15068,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -14956,7 +15068,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
14956 return sema.failWithBadStructFieldAccess(block, struct_obj, name_src, field_name);15068 return sema.failWithBadStructFieldAccess(block, struct_obj, name_src, field_name);
1495715069
14958 if (field_ptr_ty.zigTypeTag() != .Pointer) {15070 if (field_ptr_ty.zigTypeTag() != .Pointer) {
14959 return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{field_ptr_ty});15071 return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{field_ptr_ty.fmt(target)});
14960 }15072 }
14961 const field = struct_obj.fields.values()[field_index];15073 const field = struct_obj.fields.values()[field_index];
14962 const field_ptr_ty_info = field_ptr_ty.ptrInfo().data;15074 const field_ptr_ty_info = field_ptr_ty.ptrInfo().data;
...@@ -14973,7 +15085,6 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -14973,7 +15085,6 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
14973 ptr_ty_data.@"align" = field.abi_align;15085 ptr_ty_data.@"align" = field.abi_align;
14974 }15086 }
1497515087
14976 const target = sema.mod.getTarget();
14977 const actual_field_ptr_ty = try Type.ptr(sema.arena, target, ptr_ty_data);15088 const actual_field_ptr_ty = try Type.ptr(sema.arena, target, ptr_ty_data);
14978 const casted_field_ptr = try sema.coerce(block, actual_field_ptr_ty, field_ptr, ptr_src);15089 const casted_field_ptr = try sema.coerce(block, actual_field_ptr_ty, field_ptr, ptr_src);
1497915090
...@@ -15042,8 +15153,9 @@ fn analyzeMinMax(...@@ -15042,8 +15153,9 @@ fn analyzeMinMax(
15042 .max => Value.numberMax,15153 .max => Value.numberMax,
15043 else => unreachable,15154 else => unreachable,
15044 };15155 };
15156 const target = sema.mod.getTarget();
15045 const vec_len = simd_op.len orelse {15157 const vec_len = simd_op.len orelse {
15046 const result_val = opFunc(lhs_val, rhs_val);15158 const result_val = opFunc(lhs_val, rhs_val, target);
15047 return sema.addConstant(simd_op.result_ty, result_val);15159 return sema.addConstant(simd_op.result_ty, result_val);
15048 };15160 };
15049 var lhs_buf: Value.ElemValueBuffer = undefined;15161 var lhs_buf: Value.ElemValueBuffer = undefined;
...@@ -15052,7 +15164,7 @@ fn analyzeMinMax(...@@ -15052,7 +15164,7 @@ fn analyzeMinMax(
15052 for (elems) |*elem, i| {15164 for (elems) |*elem, i| {
15053 const lhs_elem_val = lhs_val.elemValueBuffer(i, &lhs_buf);15165 const lhs_elem_val = lhs_val.elemValueBuffer(i, &lhs_buf);
15054 const rhs_elem_val = rhs_val.elemValueBuffer(i, &rhs_buf);15166 const rhs_elem_val = rhs_val.elemValueBuffer(i, &rhs_buf);
15055 elem.* = opFunc(lhs_elem_val, rhs_elem_val);15167 elem.* = opFunc(lhs_elem_val, rhs_elem_val, target);
15056 }15168 }
15057 return sema.addConstant(15169 return sema.addConstant(
15058 simd_op.result_ty,15170 simd_op.result_ty,
...@@ -15078,17 +15190,17 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void...@@ -15078,17 +15190,17 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
15078 const len_src: LazySrcLoc = .{ .node_offset_builtin_call_arg2 = inst_data.src_node };15190 const len_src: LazySrcLoc = .{ .node_offset_builtin_call_arg2 = inst_data.src_node };
15079 const dest_ptr = sema.resolveInst(extra.dest);15191 const dest_ptr = sema.resolveInst(extra.dest);
15080 const dest_ptr_ty = sema.typeOf(dest_ptr);15192 const dest_ptr_ty = sema.typeOf(dest_ptr);
15193 const target = sema.mod.getTarget();
1508115194
15082 try sema.checkPtrOperand(block, dest_src, dest_ptr_ty);15195 try sema.checkPtrOperand(block, dest_src, dest_ptr_ty);
15083 if (dest_ptr_ty.isConstPtr()) {15196 if (dest_ptr_ty.isConstPtr()) {
15084 return sema.fail(block, dest_src, "cannot store through const pointer '{}'", .{dest_ptr_ty});15197 return sema.fail(block, dest_src, "cannot store through const pointer '{}'", .{dest_ptr_ty.fmt(target)});
15085 }15198 }
1508615199
15087 const uncasted_src_ptr = sema.resolveInst(extra.source);15200 const uncasted_src_ptr = sema.resolveInst(extra.source);
15088 const uncasted_src_ptr_ty = sema.typeOf(uncasted_src_ptr);15201 const uncasted_src_ptr_ty = sema.typeOf(uncasted_src_ptr);
15089 try sema.checkPtrOperand(block, src_src, uncasted_src_ptr_ty);15202 try sema.checkPtrOperand(block, src_src, uncasted_src_ptr_ty);
15090 const src_ptr_info = uncasted_src_ptr_ty.ptrInfo().data;15203 const src_ptr_info = uncasted_src_ptr_ty.ptrInfo().data;
15091 const target = sema.mod.getTarget();
15092 const wanted_src_ptr_ty = try Type.ptr(sema.arena, target, .{15204 const wanted_src_ptr_ty = try Type.ptr(sema.arena, target, .{
15093 .pointee_type = dest_ptr_ty.elemType2(),15205 .pointee_type = dest_ptr_ty.elemType2(),
15094 .@"align" = src_ptr_info.@"align",15206 .@"align" = src_ptr_info.@"align",
...@@ -15136,9 +15248,10 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void...@@ -15136,9 +15248,10 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
15136 const len_src: LazySrcLoc = .{ .node_offset_builtin_call_arg2 = inst_data.src_node };15248 const len_src: LazySrcLoc = .{ .node_offset_builtin_call_arg2 = inst_data.src_node };
15137 const dest_ptr = sema.resolveInst(extra.dest);15249 const dest_ptr = sema.resolveInst(extra.dest);
15138 const dest_ptr_ty = sema.typeOf(dest_ptr);15250 const dest_ptr_ty = sema.typeOf(dest_ptr);
15251 const target = sema.mod.getTarget();
15139 try sema.checkPtrOperand(block, dest_src, dest_ptr_ty);15252 try sema.checkPtrOperand(block, dest_src, dest_ptr_ty);
15140 if (dest_ptr_ty.isConstPtr()) {15253 if (dest_ptr_ty.isConstPtr()) {
15141 return sema.fail(block, dest_src, "cannot store through const pointer '{}'", .{dest_ptr_ty});15254 return sema.fail(block, dest_src, "cannot store through const pointer '{}'", .{dest_ptr_ty.fmt(target)});
15142 }15255 }
15143 const elem_ty = dest_ptr_ty.elemType2();15256 const elem_ty = dest_ptr_ty.elemType2();
15144 const value = try sema.coerce(block, elem_ty, sema.resolveInst(extra.byte), value_src);15257 const value = try sema.coerce(block, elem_ty, sema.resolveInst(extra.byte), value_src);
...@@ -15452,6 +15565,7 @@ fn zirPrefetch(...@@ -15452,6 +15565,7 @@ fn zirPrefetch(
15452 const ptr = sema.resolveInst(extra.lhs);15565 const ptr = sema.resolveInst(extra.lhs);
15453 try sema.checkPtrOperand(block, ptr_src, sema.typeOf(ptr));15566 try sema.checkPtrOperand(block, ptr_src, sema.typeOf(ptr));
15454 const options = try sema.coerce(block, options_ty, sema.resolveInst(extra.rhs), opts_src);15567 const options = try sema.coerce(block, options_ty, sema.resolveInst(extra.rhs), opts_src);
15568 const target = sema.mod.getTarget();
1545515569
15456 const rw = try sema.fieldVal(block, opts_src, options, "rw", opts_src);15570 const rw = try sema.fieldVal(block, opts_src, options, "rw", opts_src);
15457 const rw_val = try sema.resolveConstValue(block, opts_src, rw);15571 const rw_val = try sema.resolveConstValue(block, opts_src, rw);
...@@ -15459,7 +15573,7 @@ fn zirPrefetch(...@@ -15459,7 +15573,7 @@ fn zirPrefetch(
1545915573
15460 const locality = try sema.fieldVal(block, opts_src, options, "locality", opts_src);15574 const locality = try sema.fieldVal(block, opts_src, options, "locality", opts_src);
15461 const locality_val = try sema.resolveConstValue(block, opts_src, locality);15575 const locality_val = try sema.resolveConstValue(block, opts_src, locality);
15462 const locality_int = @intCast(u2, locality_val.toUnsignedInt());15576 const locality_int = @intCast(u2, locality_val.toUnsignedInt(target));
1546315577
15464 const cache = try sema.fieldVal(block, opts_src, options, "cache", opts_src);15578 const cache = try sema.fieldVal(block, opts_src, options, "cache", opts_src);
15465 const cache_val = try sema.resolveConstValue(block, opts_src, cache);15579 const cache_val = try sema.resolveConstValue(block, opts_src, cache);
...@@ -15492,6 +15606,7 @@ fn zirBuiltinExtern(...@@ -15492,6 +15606,7 @@ fn zirBuiltinExtern(
1549215606
15493 var ty = try sema.resolveType(block, ty_src, extra.lhs);15607 var ty = try sema.resolveType(block, ty_src, extra.lhs);
15494 const options_inst = sema.resolveInst(extra.rhs);15608 const options_inst = sema.resolveInst(extra.rhs);
15609 const target = sema.mod.getTarget();
1549515610
15496 const options = options: {15611 const options = options: {
15497 const extern_options_ty = try sema.getBuiltinType(block, options_src, "ExternOptions");15612 const extern_options_ty = try sema.getBuiltinType(block, options_src, "ExternOptions");
...@@ -15512,11 +15627,11 @@ fn zirBuiltinExtern(...@@ -15512,11 +15627,11 @@ fn zirBuiltinExtern(
15512 var library_name: ?[]const u8 = null;15627 var library_name: ?[]const u8 = null;
15513 if (!library_name_val.isNull()) {15628 if (!library_name_val.isNull()) {
15514 const payload = library_name_val.castTag(.opt_payload).?.data;15629 const payload = library_name_val.castTag(.opt_payload).?.data;
15515 library_name = try payload.toAllocatedBytes(Type.initTag(.const_slice_u8), sema.arena);15630 library_name = try payload.toAllocatedBytes(Type.initTag(.const_slice_u8), sema.arena, target);
15516 }15631 }
1551715632
15518 break :options std.builtin.ExternOptions{15633 break :options std.builtin.ExternOptions{
15519 .name = try name_val.toAllocatedBytes(Type.initTag(.const_slice_u8), sema.arena),15634 .name = try name_val.toAllocatedBytes(Type.initTag(.const_slice_u8), sema.arena, target),
15520 .library_name = library_name,15635 .library_name = library_name,
15521 .linkage = linkage_val.toEnum(std.builtin.GlobalLinkage),15636 .linkage = linkage_val.toEnum(std.builtin.GlobalLinkage),
15522 .is_thread_local = is_thread_local_val.toBool(),15637 .is_thread_local = is_thread_local_val.toBool(),
...@@ -15609,8 +15724,9 @@ fn validateVarType(...@@ -15609,8 +15724,9 @@ fn validateVarType(
15609) CompileError!void {15724) CompileError!void {
15610 if (try sema.validateRunTimeType(block, src, var_ty, is_extern)) return;15725 if (try sema.validateRunTimeType(block, src, var_ty, is_extern)) return;
1561115726
15727 const target = sema.mod.getTarget();
15612 const msg = msg: {15728 const msg = msg: {
15613 const msg = try sema.errMsg(block, src, "variable of type '{}' must be const or comptime", .{var_ty});15729 const msg = try sema.errMsg(block, src, "variable of type '{}' must be const or comptime", .{var_ty.fmt(target)});
15614 errdefer msg.destroy(sema.gpa);15730 errdefer msg.destroy(sema.gpa);
1561515731
15616 try sema.explainWhyTypeIsComptime(block, src, msg, src.toSrcLoc(block.src_decl), var_ty);15732 try sema.explainWhyTypeIsComptime(block, src, msg, src.toSrcLoc(block.src_decl), var_ty);
...@@ -15685,6 +15801,7 @@ fn explainWhyTypeIsComptime(...@@ -15685,6 +15801,7 @@ fn explainWhyTypeIsComptime(
15685 ty: Type,15801 ty: Type,
15686) CompileError!void {15802) CompileError!void {
15687 const mod = sema.mod;15803 const mod = sema.mod;
15804 const target = mod.getTarget();
15688 switch (ty.zigTypeTag()) {15805 switch (ty.zigTypeTag()) {
15689 .Bool,15806 .Bool,
15690 .Int,15807 .Int,
...@@ -15698,7 +15815,7 @@ fn explainWhyTypeIsComptime(...@@ -15698,7 +15815,7 @@ fn explainWhyTypeIsComptime(
1569815815
15699 .Fn => {15816 .Fn => {
15700 try mod.errNoteNonLazy(src_loc, msg, "use '*const {}' for a function pointer type", .{15817 try mod.errNoteNonLazy(src_loc, msg, "use '*const {}' for a function pointer type", .{
15701 ty,15818 ty.fmt(target),
15702 });15819 });
15703 },15820 },
1570415821
...@@ -15941,6 +16058,8 @@ fn fieldVal(...@@ -15941,6 +16058,8 @@ fn fieldVal(
15941 else16058 else
15942 object_ty;16059 object_ty;
1594316060
16061 const target = sema.mod.getTarget();
16062
15944 switch (inner_ty.zigTypeTag()) {16063 switch (inner_ty.zigTypeTag()) {
15945 .Array => {16064 .Array => {
15946 if (mem.eql(u8, field_name, "len")) {16065 if (mem.eql(u8, field_name, "len")) {
...@@ -15953,7 +16072,7 @@ fn fieldVal(...@@ -15953,7 +16072,7 @@ fn fieldVal(
15953 block,16072 block,
15954 field_name_src,16073 field_name_src,
15955 "no member named '{s}' in '{}'",16074 "no member named '{s}' in '{}'",
15956 .{ field_name, object_ty },16075 .{ field_name, object_ty.fmt(target) },
15957 );16076 );
15958 }16077 }
15959 },16078 },
...@@ -15977,7 +16096,7 @@ fn fieldVal(...@@ -15977,7 +16096,7 @@ fn fieldVal(
15977 block,16096 block,
15978 field_name_src,16097 field_name_src,
15979 "no member named '{s}' in '{}'",16098 "no member named '{s}' in '{}'",
15980 .{ field_name, object_ty },16099 .{ field_name, object_ty.fmt(target) },
15981 );16100 );
15982 }16101 }
15983 } else if (ptr_info.pointee_type.zigTypeTag() == .Array) {16102 } else if (ptr_info.pointee_type.zigTypeTag() == .Array) {
...@@ -15991,7 +16110,7 @@ fn fieldVal(...@@ -15991,7 +16110,7 @@ fn fieldVal(
15991 block,16110 block,
15992 field_name_src,16111 field_name_src,
15993 "no member named '{s}' in '{}'",16112 "no member named '{s}' in '{}'",
15994 .{ field_name, ptr_info.pointee_type },16113 .{ field_name, ptr_info.pointee_type.fmt(target) },
15995 );16114 );
15996 }16115 }
15997 }16116 }
...@@ -16013,7 +16132,7 @@ fn fieldVal(...@@ -16013,7 +16132,7 @@ fn fieldVal(
16013 break :blk entry.key_ptr.*;16132 break :blk entry.key_ptr.*;
16014 }16133 }
16015 return sema.fail(block, src, "no error named '{s}' in '{}'", .{16134 return sema.fail(block, src, "no error named '{s}' in '{}'", .{
16016 field_name, child_type,16135 field_name, child_type.fmt(target),
16017 });16136 });
16018 } else (try sema.mod.getErrorValue(field_name)).key;16137 } else (try sema.mod.getErrorValue(field_name)).key;
1601916138
...@@ -16067,10 +16186,10 @@ fn fieldVal(...@@ -16067,10 +16186,10 @@ fn fieldVal(
16067 else => unreachable,16186 else => unreachable,
16068 };16187 };
16069 return sema.fail(block, src, "{s} '{}' has no member named '{s}'", .{16188 return sema.fail(block, src, "{s} '{}' has no member named '{s}'", .{
16070 kw_name, child_type, field_name,16189 kw_name, child_type.fmt(target), field_name,
16071 });16190 });
16072 },16191 },
16073 else => return sema.fail(block, src, "type '{}' has no members", .{child_type}),16192 else => return sema.fail(block, src, "type '{}' has no members", .{child_type.fmt(target)}),
16074 }16193 }
16075 },16194 },
16076 .Struct => if (is_pointer_to) {16195 .Struct => if (is_pointer_to) {
...@@ -16089,7 +16208,7 @@ fn fieldVal(...@@ -16089,7 +16208,7 @@ fn fieldVal(
16089 },16208 },
16090 else => {},16209 else => {},
16091 }16210 }
16092 return sema.fail(block, src, "type '{}' does not support field access", .{object_ty});16211 return sema.fail(block, src, "type '{}' does not support field access", .{object_ty.fmt(target)});
16093}16212}
1609416213
16095fn fieldPtr(16214fn fieldPtr(
...@@ -16103,11 +16222,12 @@ fn fieldPtr(...@@ -16103,11 +16222,12 @@ fn fieldPtr(
16103 // When editing this function, note that there is corresponding logic to be edited16222 // When editing this function, note that there is corresponding logic to be edited
16104 // in `fieldVal`. This function takes a pointer and returns a pointer.16223 // in `fieldVal`. This function takes a pointer and returns a pointer.
1610516224
16225 const target = sema.mod.getTarget();
16106 const object_ptr_src = src; // TODO better source location16226 const object_ptr_src = src; // TODO better source location
16107 const object_ptr_ty = sema.typeOf(object_ptr);16227 const object_ptr_ty = sema.typeOf(object_ptr);
16108 const object_ty = switch (object_ptr_ty.zigTypeTag()) {16228 const object_ty = switch (object_ptr_ty.zigTypeTag()) {
16109 .Pointer => object_ptr_ty.elemType(),16229 .Pointer => object_ptr_ty.elemType(),
16110 else => return sema.fail(block, object_ptr_src, "expected pointer, found '{}'", .{object_ptr_ty}),16230 else => return sema.fail(block, object_ptr_src, "expected pointer, found '{}'", .{object_ptr_ty.fmt(target)}),
16111 };16231 };
1611216232
16113 // Zig allows dereferencing a single pointer during field lookup. Note that16233 // Zig allows dereferencing a single pointer during field lookup. Note that
...@@ -16120,8 +16240,6 @@ fn fieldPtr(...@@ -16120,8 +16240,6 @@ fn fieldPtr(
16120 else16240 else
16121 object_ty;16241 object_ty;
1612216242
16123 const target = sema.mod.getTarget();
16124
16125 switch (inner_ty.zigTypeTag()) {16243 switch (inner_ty.zigTypeTag()) {
16126 .Array => {16244 .Array => {
16127 if (mem.eql(u8, field_name, "len")) {16245 if (mem.eql(u8, field_name, "len")) {
...@@ -16137,7 +16255,7 @@ fn fieldPtr(...@@ -16137,7 +16255,7 @@ fn fieldPtr(
16137 block,16255 block,
16138 field_name_src,16256 field_name_src,
16139 "no member named '{s}' in '{}'",16257 "no member named '{s}' in '{}'",
16140 .{ field_name, object_ty },16258 .{ field_name, object_ty.fmt(target) },
16141 );16259 );
16142 }16260 }
16143 },16261 },
...@@ -16177,7 +16295,7 @@ fn fieldPtr(...@@ -16177,7 +16295,7 @@ fn fieldPtr(
1617716295
16178 return sema.analyzeDeclRef(try anon_decl.finish(16296 return sema.analyzeDeclRef(try anon_decl.finish(
16179 Type.usize,16297 Type.usize,
16180 try Value.Tag.int_u64.create(anon_decl.arena(), val.sliceLen()),16298 try Value.Tag.int_u64.create(anon_decl.arena(), val.sliceLen(target)),
16181 0, // default alignment16299 0, // default alignment
16182 ));16300 ));
16183 }16301 }
...@@ -16195,7 +16313,7 @@ fn fieldPtr(...@@ -16195,7 +16313,7 @@ fn fieldPtr(
16195 block,16313 block,
16196 field_name_src,16314 field_name_src,
16197 "no member named '{s}' in '{}'",16315 "no member named '{s}' in '{}'",
16198 .{ field_name, object_ty },16316 .{ field_name, object_ty.fmt(target) },
16199 );16317 );
16200 }16318 }
16201 },16319 },
...@@ -16219,7 +16337,7 @@ fn fieldPtr(...@@ -16219,7 +16337,7 @@ fn fieldPtr(
16219 break :blk entry.key_ptr.*;16337 break :blk entry.key_ptr.*;
16220 }16338 }
16221 return sema.fail(block, src, "no error named '{s}' in '{}'", .{16339 return sema.fail(block, src, "no error named '{s}' in '{}'", .{
16222 field_name, child_type,16340 field_name, child_type.fmt(target),
16223 });16341 });
16224 } else (try sema.mod.getErrorValue(field_name)).key;16342 } else (try sema.mod.getErrorValue(field_name)).key;
1622516343
...@@ -16277,7 +16395,7 @@ fn fieldPtr(...@@ -16277,7 +16395,7 @@ fn fieldPtr(
16277 }16395 }
16278 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);16396 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);
16279 },16397 },
16280 else => return sema.fail(block, src, "type '{}' has no members", .{child_type}),16398 else => return sema.fail(block, src, "type '{}' has no members", .{child_type.fmt(target)}),
16281 }16399 }
16282 },16400 },
16283 .Struct => {16401 .Struct => {
...@@ -16296,7 +16414,7 @@ fn fieldPtr(...@@ -16296,7 +16414,7 @@ fn fieldPtr(
16296 },16414 },
16297 else => {},16415 else => {},
16298 }16416 }
16299 return sema.fail(block, src, "type '{}' does not support field access (fieldPtr, {}.{s})", .{ object_ty, object_ptr_ty, field_name });16417 return sema.fail(block, src, "type '{}' does not support field access (fieldPtr, {}.{s})", .{ object_ty.fmt(target), object_ptr_ty.fmt(target), field_name });
16300}16418}
1630116419
16302fn fieldCallBind(16420fn fieldCallBind(
...@@ -16310,12 +16428,13 @@ fn fieldCallBind(...@@ -16310,12 +16428,13 @@ fn fieldCallBind(
16310 // When editing this function, note that there is corresponding logic to be edited16428 // When editing this function, note that there is corresponding logic to be edited
16311 // in `fieldVal`. This function takes a pointer and returns a pointer.16429 // in `fieldVal`. This function takes a pointer and returns a pointer.
1631216430
16431 const target = sema.mod.getTarget();
16313 const raw_ptr_src = src; // TODO better source location16432 const raw_ptr_src = src; // TODO better source location
16314 const raw_ptr_ty = sema.typeOf(raw_ptr);16433 const raw_ptr_ty = sema.typeOf(raw_ptr);
16315 const inner_ty = if (raw_ptr_ty.zigTypeTag() == .Pointer and raw_ptr_ty.ptrSize() == .One)16434 const inner_ty = if (raw_ptr_ty.zigTypeTag() == .Pointer and raw_ptr_ty.ptrSize() == .One)
16316 raw_ptr_ty.childType()16435 raw_ptr_ty.childType()
16317 else16436 else
16318 return sema.fail(block, raw_ptr_src, "expected single pointer, found '{}'", .{raw_ptr_ty});16437 return sema.fail(block, raw_ptr_src, "expected single pointer, found '{}'", .{raw_ptr_ty.fmt(target)});
1631916438
16320 // Optionally dereference a second pointer to get the concrete type.16439 // Optionally dereference a second pointer to get the concrete type.
16321 const is_double_ptr = inner_ty.zigTypeTag() == .Pointer and inner_ty.ptrSize() == .One;16440 const is_double_ptr = inner_ty.zigTypeTag() == .Pointer and inner_ty.ptrSize() == .One;
...@@ -16375,7 +16494,7 @@ fn fieldCallBind(...@@ -16375,7 +16494,7 @@ fn fieldCallBind(
16375 first_param_type.zigTypeTag() == .Pointer and16494 first_param_type.zigTypeTag() == .Pointer and
16376 (first_param_type.ptrSize() == .One or16495 (first_param_type.ptrSize() == .One or
16377 first_param_type.ptrSize() == .C) and16496 first_param_type.ptrSize() == .C) and
16378 first_param_type.childType().eql(concrete_ty)))16497 first_param_type.childType().eql(concrete_ty, target)))
16379 {16498 {
16380 // zig fmt: on16499 // zig fmt: on
16381 // TODO: bound fn calls on rvalues should probably16500 // TODO: bound fn calls on rvalues should probably
...@@ -16386,7 +16505,7 @@ fn fieldCallBind(...@@ -16386,7 +16505,7 @@ fn fieldCallBind(
16386 .arg0_inst = object_ptr,16505 .arg0_inst = object_ptr,
16387 });16506 });
16388 return sema.addConstant(ty, value);16507 return sema.addConstant(ty, value);
16389 } else if (first_param_type.eql(concrete_ty)) {16508 } else if (first_param_type.eql(concrete_ty, target)) {
16390 var deref = try sema.analyzeLoad(block, src, object_ptr, src);16509 var deref = try sema.analyzeLoad(block, src, object_ptr, src);
16391 const ty = Type.Tag.bound_fn.init();16510 const ty = Type.Tag.bound_fn.init();
16392 const value = try Value.Tag.bound_fn.create(arena, .{16511 const value = try Value.Tag.bound_fn.create(arena, .{
...@@ -16402,7 +16521,7 @@ fn fieldCallBind(...@@ -16402,7 +16521,7 @@ fn fieldCallBind(
16402 else => {},16521 else => {},
16403 }16522 }
1640416523
16405 return sema.fail(block, src, "type '{}' has no field or member function named '{s}'", .{ concrete_ty, field_name });16524 return sema.fail(block, src, "type '{}' has no field or member function named '{s}'", .{ concrete_ty.fmt(target), field_name });
16406}16525}
1640716526
16408fn finishFieldCallBind(16527fn finishFieldCallBind(
...@@ -16540,10 +16659,11 @@ fn structFieldPtrByIndex(...@@ -16540,10 +16659,11 @@ fn structFieldPtrByIndex(
16540 .@"addrspace" = struct_ptr_ty_info.@"addrspace",16659 .@"addrspace" = struct_ptr_ty_info.@"addrspace",
16541 };16660 };
1654216661
16662 const target = sema.mod.getTarget();
16663
16543 // TODO handle when the struct pointer is overaligned, we should return a potentially16664 // TODO handle when the struct pointer is overaligned, we should return a potentially
16544 // over-aligned field pointer too.16665 // over-aligned field pointer too.
16545 if (struct_obj.layout == .Packed) {16666 if (struct_obj.layout == .Packed) {
16546 const target = sema.mod.getTarget();
16547 comptime assert(Type.packed_struct_layout_version == 2);16667 comptime assert(Type.packed_struct_layout_version == 2);
1654816668
16549 var running_bits: u16 = 0;16669 var running_bits: u16 = 0;
...@@ -16567,7 +16687,6 @@ fn structFieldPtrByIndex(...@@ -16567,7 +16687,6 @@ fn structFieldPtrByIndex(
16567 ptr_ty_data.@"align" = field.abi_align;16687 ptr_ty_data.@"align" = field.abi_align;
16568 }16688 }
1656916689
16570 const target = sema.mod.getTarget();
16571 const ptr_field_ty = try Type.ptr(sema.arena, target, ptr_ty_data);16690 const ptr_field_ty = try Type.ptr(sema.arena, target, ptr_ty_data);
1657216691
16573 if (field.is_comptime) {16692 if (field.is_comptime) {
...@@ -16667,14 +16786,15 @@ fn tupleFieldIndex(...@@ -16667,14 +16786,15 @@ fn tupleFieldIndex(
16667 field_name: []const u8,16786 field_name: []const u8,
16668 field_name_src: LazySrcLoc,16787 field_name_src: LazySrcLoc,
16669) CompileError!u32 {16788) CompileError!u32 {
16789 const target = sema.mod.getTarget();
16670 const field_index = std.fmt.parseUnsigned(u32, field_name, 10) catch |err| {16790 const field_index = std.fmt.parseUnsigned(u32, field_name, 10) catch |err| {
16671 return sema.fail(block, field_name_src, "tuple {} has no such field '{s}': {s}", .{16791 return sema.fail(block, field_name_src, "tuple {} has no such field '{s}': {s}", .{
16672 tuple_ty, field_name, @errorName(err),16792 tuple_ty.fmt(target), field_name, @errorName(err),
16673 });16793 });
16674 };16794 };
16675 if (field_index >= tuple_ty.structFieldCount()) {16795 if (field_index >= tuple_ty.structFieldCount()) {
16676 return sema.fail(block, field_name_src, "tuple {} has no such field '{s}'", .{16796 return sema.fail(block, field_name_src, "tuple {} has no such field '{s}'", .{
16677 tuple_ty, field_name,16797 tuple_ty.fmt(target), field_name,
16678 });16798 });
16679 }16799 }
16680 return field_index;16800 return field_index;
...@@ -16749,7 +16869,7 @@ fn unionFieldPtr(...@@ -16749,7 +16869,7 @@ fn unionFieldPtr(
16749 // .data = field_index,16869 // .data = field_index,
16750 //};16870 //};
16751 //const field_tag = Value.initPayload(&field_tag_buf.base);16871 //const field_tag = Value.initPayload(&field_tag_buf.base);
16752 //const tag_matches = tag_and_val.tag.eql(field_tag, union_obj.tag_ty);16872 //const tag_matches = tag_and_val.tag.eql(field_tag, union_obj.tag_ty, target);
16753 //if (!tag_matches) {16873 //if (!tag_matches) {
16754 // // TODO enhance this saying which one was active16874 // // TODO enhance this saying which one was active
16755 // // and which one was accessed, and showing where the union was declared.16875 // // and which one was accessed, and showing where the union was declared.
...@@ -16798,7 +16918,8 @@ fn unionFieldVal(...@@ -16798,7 +16918,8 @@ fn unionFieldVal(
16798 .data = field_index,16918 .data = field_index,
16799 };16919 };
16800 const field_tag = Value.initPayload(&field_tag_buf.base);16920 const field_tag = Value.initPayload(&field_tag_buf.base);
16801 const tag_matches = tag_and_val.tag.eql(field_tag, union_obj.tag_ty);16921 const target = sema.mod.getTarget();
16922 const tag_matches = tag_and_val.tag.eql(field_tag, union_obj.tag_ty, target);
16802 switch (union_obj.layout) {16923 switch (union_obj.layout) {
16803 .Auto => {16924 .Auto => {
16804 if (tag_matches) {16925 if (tag_matches) {
...@@ -16813,7 +16934,7 @@ fn unionFieldVal(...@@ -16813,7 +16934,7 @@ fn unionFieldVal(
16813 if (tag_matches) {16934 if (tag_matches) {
16814 return sema.addConstant(field.ty, tag_and_val.val);16935 return sema.addConstant(field.ty, tag_and_val.val);
16815 } else {16936 } else {
16816 const old_ty = union_ty.unionFieldType(tag_and_val.tag);16937 const old_ty = union_ty.unionFieldType(tag_and_val.tag, target);
16817 const new_val = try sema.bitCastVal(block, src, tag_and_val.val, old_ty, field.ty, 0);16938 const new_val = try sema.bitCastVal(block, src, tag_and_val.val, old_ty, field.ty, 0);
16818 return sema.addConstant(field.ty, new_val);16939 return sema.addConstant(field.ty, new_val);
16819 }16940 }
...@@ -16835,19 +16956,19 @@ fn elemPtr(...@@ -16835,19 +16956,19 @@ fn elemPtr(
16835) CompileError!Air.Inst.Ref {16956) CompileError!Air.Inst.Ref {
16836 const indexable_ptr_src = src; // TODO better source location16957 const indexable_ptr_src = src; // TODO better source location
16837 const indexable_ptr_ty = sema.typeOf(indexable_ptr);16958 const indexable_ptr_ty = sema.typeOf(indexable_ptr);
16959 const target = sema.mod.getTarget();
16838 const indexable_ty = switch (indexable_ptr_ty.zigTypeTag()) {16960 const indexable_ty = switch (indexable_ptr_ty.zigTypeTag()) {
16839 .Pointer => indexable_ptr_ty.elemType(),16961 .Pointer => indexable_ptr_ty.elemType(),
16840 else => return sema.fail(block, indexable_ptr_src, "expected pointer, found '{}'", .{indexable_ptr_ty}),16962 else => return sema.fail(block, indexable_ptr_src, "expected pointer, found '{}'", .{indexable_ptr_ty.fmt(target)}),
16841 };16963 };
16842 if (!indexable_ty.isIndexable()) {16964 if (!indexable_ty.isIndexable()) {
16843 return sema.fail(block, src, "element access of non-indexable type '{}'", .{indexable_ty});16965 return sema.fail(block, src, "element access of non-indexable type '{}'", .{indexable_ty.fmt(target)});
16844 }16966 }
1684516967
16846 switch (indexable_ty.zigTypeTag()) {16968 switch (indexable_ty.zigTypeTag()) {
16847 .Pointer => {16969 .Pointer => {
16848 // In all below cases, we have to deref the ptr operand to get the actual indexable pointer.16970 // In all below cases, we have to deref the ptr operand to get the actual indexable pointer.
16849 const indexable = try sema.analyzeLoad(block, indexable_ptr_src, indexable_ptr, indexable_ptr_src);16971 const indexable = try sema.analyzeLoad(block, indexable_ptr_src, indexable_ptr, indexable_ptr_src);
16850 const target = sema.mod.getTarget();
16851 const result_ty = try indexable_ty.elemPtrType(sema.arena, target);16972 const result_ty = try indexable_ty.elemPtrType(sema.arena, target);
16852 switch (indexable_ty.ptrSize()) {16973 switch (indexable_ty.ptrSize()) {
16853 .Slice => return sema.elemPtrSlice(block, indexable_ptr_src, indexable, elem_index_src, elem_index),16974 .Slice => return sema.elemPtrSlice(block, indexable_ptr_src, indexable, elem_index_src, elem_index),
...@@ -16858,8 +16979,8 @@ fn elemPtr(...@@ -16858,8 +16979,8 @@ fn elemPtr(
16858 const runtime_src = rs: {16979 const runtime_src = rs: {
16859 const ptr_val = maybe_ptr_val orelse break :rs indexable_ptr_src;16980 const ptr_val = maybe_ptr_val orelse break :rs indexable_ptr_src;
16860 const index_val = maybe_index_val orelse break :rs elem_index_src;16981 const index_val = maybe_index_val orelse break :rs elem_index_src;
16861 const index = @intCast(usize, index_val.toUnsignedInt());16982 const index = @intCast(usize, index_val.toUnsignedInt(target));
16862 const elem_ptr = try ptr_val.elemPtr(indexable_ty, sema.arena, index);16983 const elem_ptr = try ptr_val.elemPtr(indexable_ty, sema.arena, index, target);
16863 return sema.addConstant(result_ty, elem_ptr);16984 return sema.addConstant(result_ty, elem_ptr);
16864 };16985 };
1686516986
...@@ -16876,7 +16997,7 @@ fn elemPtr(...@@ -16876,7 +16997,7 @@ fn elemPtr(
16876 .Struct => {16997 .Struct => {
16877 // Tuple field access.16998 // Tuple field access.
16878 const index_val = try sema.resolveConstValue(block, elem_index_src, elem_index);16999 const index_val = try sema.resolveConstValue(block, elem_index_src, elem_index);
16879 const index = @intCast(u32, index_val.toUnsignedInt());17000 const index = @intCast(u32, index_val.toUnsignedInt(target));
16880 return sema.tupleFieldPtr(block, src, indexable_ptr, elem_index_src, index);17001 return sema.tupleFieldPtr(block, src, indexable_ptr, elem_index_src, index);
16881 },17002 },
16882 else => unreachable,17003 else => unreachable,
...@@ -16893,9 +17014,10 @@ fn elemVal(...@@ -16893,9 +17014,10 @@ fn elemVal(
16893) CompileError!Air.Inst.Ref {17014) CompileError!Air.Inst.Ref {
16894 const indexable_src = src; // TODO better source location17015 const indexable_src = src; // TODO better source location
16895 const indexable_ty = sema.typeOf(indexable);17016 const indexable_ty = sema.typeOf(indexable);
17017 const target = sema.mod.getTarget();
1689617018
16897 if (!indexable_ty.isIndexable()) {17019 if (!indexable_ty.isIndexable()) {
16898 return sema.fail(block, src, "element access of non-indexable type '{}'", .{indexable_ty});17020 return sema.fail(block, src, "element access of non-indexable type '{}'", .{indexable_ty.fmt(target)});
16899 }17021 }
1690017022
16901 // TODO in case of a vector of pointers, we need to detect whether the element17023 // TODO in case of a vector of pointers, we need to detect whether the element
...@@ -16912,7 +17034,7 @@ fn elemVal(...@@ -16912,7 +17034,7 @@ fn elemVal(
16912 const runtime_src = rs: {17034 const runtime_src = rs: {
16913 const indexable_val = maybe_indexable_val orelse break :rs indexable_src;17035 const indexable_val = maybe_indexable_val orelse break :rs indexable_src;
16914 const index_val = maybe_index_val orelse break :rs elem_index_src;17036 const index_val = maybe_index_val orelse break :rs elem_index_src;
16915 const index = @intCast(usize, index_val.toUnsignedInt());17037 const index = @intCast(usize, index_val.toUnsignedInt(target));
16916 const elem_ty = indexable_ty.elemType2();17038 const elem_ty = indexable_ty.elemType2();
1691717039
16918 var payload: Value.Payload.ElemPtr = .{ .data = .{17040 var payload: Value.Payload.ElemPtr = .{ .data = .{
...@@ -16945,7 +17067,7 @@ fn elemVal(...@@ -16945,7 +17067,7 @@ fn elemVal(
16945 .Struct => {17067 .Struct => {
16946 // Tuple field access.17068 // Tuple field access.
16947 const index_val = try sema.resolveConstValue(block, elem_index_src, elem_index);17069 const index_val = try sema.resolveConstValue(block, elem_index_src, elem_index);
16948 const index = @intCast(u32, index_val.toUnsignedInt());17070 const index = @intCast(u32, index_val.toUnsignedInt(target));
16949 return tupleField(sema, block, indexable_src, indexable, elem_index_src, index);17071 return tupleField(sema, block, indexable_src, indexable, elem_index_src, index);
16950 },17072 },
16951 else => unreachable,17073 else => unreachable,
...@@ -17056,9 +17178,10 @@ fn elemValArray(...@@ -17056,9 +17178,10 @@ fn elemValArray(
17056 const maybe_undef_array_val = try sema.resolveMaybeUndefVal(block, array_src, array);17178 const maybe_undef_array_val = try sema.resolveMaybeUndefVal(block, array_src, array);
17057 // index must be defined since it can access out of bounds17179 // index must be defined since it can access out of bounds
17058 const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);17180 const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);
17181 const target = sema.mod.getTarget();
1705917182
17060 if (maybe_index_val) |index_val| {17183 if (maybe_index_val) |index_val| {
17061 const index = @intCast(usize, index_val.toUnsignedInt());17184 const index = @intCast(usize, index_val.toUnsignedInt(target));
17062 if (index >= array_len_s) {17185 if (index >= array_len_s) {
17063 const sentinel_label: []const u8 = if (array_sent) " +1 (sentinel)" else "";17186 const sentinel_label: []const u8 = if (array_sent) " +1 (sentinel)" else "";
17064 return sema.fail(block, elem_index_src, "index {d} outside array of length {d}{s}", .{ index, array_len, sentinel_label });17187 return sema.fail(block, elem_index_src, "index {d} outside array of length {d}{s}", .{ index, array_len, sentinel_label });
...@@ -17069,7 +17192,7 @@ fn elemValArray(...@@ -17069,7 +17192,7 @@ fn elemValArray(
17069 return sema.addConstUndef(elem_ty);17192 return sema.addConstUndef(elem_ty);
17070 }17193 }
17071 if (maybe_index_val) |index_val| {17194 if (maybe_index_val) |index_val| {
17072 const index = @intCast(usize, index_val.toUnsignedInt());17195 const index = @intCast(usize, index_val.toUnsignedInt(target));
17073 const elem_val = try array_val.elemValue(sema.arena, index);17196 const elem_val = try array_val.elemValue(sema.arena, index);
17074 return sema.addConstant(elem_ty, elem_val);17197 return sema.addConstant(elem_ty, elem_val);
17075 }17198 }
...@@ -17114,7 +17237,7 @@ fn elemPtrArray(...@@ -17114,7 +17237,7 @@ fn elemPtrArray(
17114 const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);17237 const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);
1711517238
17116 if (maybe_index_val) |index_val| {17239 if (maybe_index_val) |index_val| {
17117 const index = @intCast(usize, index_val.toUnsignedInt());17240 const index = @intCast(usize, index_val.toUnsignedInt(target));
17118 if (index >= array_len_s) {17241 if (index >= array_len_s) {
17119 const sentinel_label: []const u8 = if (array_sent) " +1 (sentinel)" else "";17242 const sentinel_label: []const u8 = if (array_sent) " +1 (sentinel)" else "";
17120 return sema.fail(block, elem_index_src, "index {d} outside array of length {d}{s}", .{ index, array_len, sentinel_label });17243 return sema.fail(block, elem_index_src, "index {d} outside array of length {d}{s}", .{ index, array_len, sentinel_label });
...@@ -17125,8 +17248,8 @@ fn elemPtrArray(...@@ -17125,8 +17248,8 @@ fn elemPtrArray(
17125 return sema.addConstUndef(elem_ptr_ty);17248 return sema.addConstUndef(elem_ptr_ty);
17126 }17249 }
17127 if (maybe_index_val) |index_val| {17250 if (maybe_index_val) |index_val| {
17128 const index = @intCast(usize, index_val.toUnsignedInt());17251 const index = @intCast(usize, index_val.toUnsignedInt(target));
17129 const elem_ptr = try array_ptr_val.elemPtr(array_ptr_ty, sema.arena, index);17252 const elem_ptr = try array_ptr_val.elemPtr(array_ptr_ty, sema.arena, index, target);
17130 return sema.addConstant(elem_ptr_ty, elem_ptr);17253 return sema.addConstant(elem_ptr_ty, elem_ptr);
17131 }17254 }
17132 }17255 }
...@@ -17162,16 +17285,17 @@ fn elemValSlice(...@@ -17162,16 +17285,17 @@ fn elemValSlice(
17162 const maybe_slice_val = try sema.resolveDefinedValue(block, slice_src, slice);17285 const maybe_slice_val = try sema.resolveDefinedValue(block, slice_src, slice);
17163 // index must be defined since it can index out of bounds17286 // index must be defined since it can index out of bounds
17164 const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);17287 const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);
17288 const target = sema.mod.getTarget();
1716517289
17166 if (maybe_slice_val) |slice_val| {17290 if (maybe_slice_val) |slice_val| {
17167 runtime_src = elem_index_src;17291 runtime_src = elem_index_src;
17168 const slice_len = slice_val.sliceLen();17292 const slice_len = slice_val.sliceLen(target);
17169 const slice_len_s = slice_len + @boolToInt(slice_sent);17293 const slice_len_s = slice_len + @boolToInt(slice_sent);
17170 if (slice_len_s == 0) {17294 if (slice_len_s == 0) {
17171 return sema.fail(block, elem_index_src, "indexing into empty slice", .{});17295 return sema.fail(block, elem_index_src, "indexing into empty slice", .{});
17172 }17296 }
17173 if (maybe_index_val) |index_val| {17297 if (maybe_index_val) |index_val| {
17174 const index = @intCast(usize, index_val.toUnsignedInt());17298 const index = @intCast(usize, index_val.toUnsignedInt(target));
17175 if (index >= slice_len_s) {17299 if (index >= slice_len_s) {
17176 const sentinel_label: []const u8 = if (slice_sent) " +1 (sentinel)" else "";17300 const sentinel_label: []const u8 = if (slice_sent) " +1 (sentinel)" else "";
17177 return sema.fail(block, elem_index_src, "index {d} outside slice of length {d}{s}", .{ index, slice_len, sentinel_label });17301 return sema.fail(block, elem_index_src, "index {d} outside slice of length {d}{s}", .{ index, slice_len, sentinel_label });
...@@ -17192,7 +17316,7 @@ fn elemValSlice(...@@ -17192,7 +17316,7 @@ fn elemValSlice(
17192 try sema.requireRuntimeBlock(block, runtime_src);17316 try sema.requireRuntimeBlock(block, runtime_src);
17193 if (block.wantSafety()) {17317 if (block.wantSafety()) {
17194 const len_inst = if (maybe_slice_val) |slice_val|17318 const len_inst = if (maybe_slice_val) |slice_val|
17195 try sema.addIntUnsigned(Type.usize, slice_val.sliceLen())17319 try sema.addIntUnsigned(Type.usize, slice_val.sliceLen(target))
17196 else17320 else
17197 try block.addTyOp(.slice_len, Type.usize, slice);17321 try block.addTyOp(.slice_len, Type.usize, slice);
17198 const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt;17322 const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt;
...@@ -17223,18 +17347,18 @@ fn elemPtrSlice(...@@ -17223,18 +17347,18 @@ fn elemPtrSlice(
17223 if (slice_val.isUndef()) {17347 if (slice_val.isUndef()) {
17224 return sema.addConstUndef(elem_ptr_ty);17348 return sema.addConstUndef(elem_ptr_ty);
17225 }17349 }
17226 const slice_len = slice_val.sliceLen();17350 const slice_len = slice_val.sliceLen(target);
17227 const slice_len_s = slice_len + @boolToInt(slice_sent);17351 const slice_len_s = slice_len + @boolToInt(slice_sent);
17228 if (slice_len_s == 0) {17352 if (slice_len_s == 0) {
17229 return sema.fail(block, elem_index_src, "indexing into empty slice", .{});17353 return sema.fail(block, elem_index_src, "indexing into empty slice", .{});
17230 }17354 }
17231 if (maybe_index_val) |index_val| {17355 if (maybe_index_val) |index_val| {
17232 const index = @intCast(usize, index_val.toUnsignedInt());17356 const index = @intCast(usize, index_val.toUnsignedInt(target));
17233 if (index >= slice_len_s) {17357 if (index >= slice_len_s) {
17234 const sentinel_label: []const u8 = if (slice_sent) " +1 (sentinel)" else "";17358 const sentinel_label: []const u8 = if (slice_sent) " +1 (sentinel)" else "";
17235 return sema.fail(block, elem_index_src, "index {d} outside slice of length {d}{s}", .{ index, slice_len, sentinel_label });17359 return sema.fail(block, elem_index_src, "index {d} outside slice of length {d}{s}", .{ index, slice_len, sentinel_label });
17236 }17360 }
17237 const elem_ptr_val = try slice_val.elemPtr(slice_ty, sema.arena, index);17361 const elem_ptr_val = try slice_val.elemPtr(slice_ty, sema.arena, index, target);
17238 return sema.addConstant(elem_ptr_ty, elem_ptr_val);17362 return sema.addConstant(elem_ptr_ty, elem_ptr_val);
17239 }17363 }
17240 }17364 }
...@@ -17245,7 +17369,7 @@ fn elemPtrSlice(...@@ -17245,7 +17369,7 @@ fn elemPtrSlice(
17245 const len_inst = len: {17369 const len_inst = len: {
17246 if (maybe_undef_slice_val) |slice_val|17370 if (maybe_undef_slice_val) |slice_val|
17247 if (!slice_val.isUndef())17371 if (!slice_val.isUndef())
17248 break :len try sema.addIntUnsigned(Type.usize, slice_val.sliceLen());17372 break :len try sema.addIntUnsigned(Type.usize, slice_val.sliceLen(target));
17249 break :len try block.addTyOp(.slice_len, Type.usize, slice);17373 break :len try block.addTyOp(.slice_len, Type.usize, slice);
17250 };17374 };
17251 const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt;17375 const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt;
...@@ -17270,12 +17394,12 @@ fn coerce(...@@ -17270,12 +17394,12 @@ fn coerce(
17270 const dest_ty_src = inst_src; // TODO better source location17394 const dest_ty_src = inst_src; // TODO better source location
17271 const dest_ty = try sema.resolveTypeFields(block, dest_ty_src, dest_ty_unresolved);17395 const dest_ty = try sema.resolveTypeFields(block, dest_ty_src, dest_ty_unresolved);
17272 const inst_ty = try sema.resolveTypeFields(block, inst_src, sema.typeOf(inst));17396 const inst_ty = try sema.resolveTypeFields(block, inst_src, sema.typeOf(inst));
17397 const target = sema.mod.getTarget();
17273 // If the types are the same, we can return the operand.17398 // If the types are the same, we can return the operand.
17274 if (dest_ty.eql(inst_ty))17399 if (dest_ty.eql(inst_ty, target))
17275 return inst;17400 return inst;
1727617401
17277 const arena = sema.arena;17402 const arena = sema.arena;
17278 const target = sema.mod.getTarget();
17279 const maybe_inst_val = try sema.resolveMaybeUndefVal(block, inst_src, inst);17403 const maybe_inst_val = try sema.resolveMaybeUndefVal(block, inst_src, inst);
1728017404
17281 const in_memory_result = try sema.coerceInMemoryAllowed(block, dest_ty, inst_ty, false, target, dest_ty_src, inst_src);17405 const in_memory_result = try sema.coerceInMemoryAllowed(block, dest_ty, inst_ty, false, target, dest_ty_src, inst_src);
...@@ -17379,7 +17503,7 @@ fn coerce(...@@ -17379,7 +17503,7 @@ fn coerce(
17379 // *[N:s]T to [*]T17503 // *[N:s]T to [*]T
17380 if (dest_info.sentinel) |dst_sentinel| {17504 if (dest_info.sentinel) |dst_sentinel| {
17381 if (array_ty.sentinel()) |src_sentinel| {17505 if (array_ty.sentinel()) |src_sentinel| {
17382 if (src_sentinel.eql(dst_sentinel, dst_elem_type)) {17506 if (src_sentinel.eql(dst_sentinel, dst_elem_type, target)) {
17383 return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src);17507 return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src);
17384 }17508 }
17385 }17509 }
...@@ -17448,7 +17572,7 @@ fn coerce(...@@ -17448,7 +17572,7 @@ fn coerce(
17448 }17572 }
17449 if (inst_info.size == .Slice) {17573 if (inst_info.size == .Slice) {
17450 if (dest_info.sentinel == null or inst_info.sentinel == null or17574 if (dest_info.sentinel == null or inst_info.sentinel == null or
17451 !dest_info.sentinel.?.eql(inst_info.sentinel.?, dest_info.pointee_type))17575 !dest_info.sentinel.?.eql(inst_info.sentinel.?, dest_info.pointee_type, target))
17452 break :p;17576 break :p;
1745317577
17454 const slice_ptr = try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty);17578 const slice_ptr = try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty);
...@@ -17515,7 +17639,7 @@ fn coerce(...@@ -17515,7 +17639,7 @@ fn coerce(
17515 }17639 }
1751617640
17517 if (dest_info.sentinel == null or inst_info.sentinel == null or17641 if (dest_info.sentinel == null or inst_info.sentinel == null or
17518 !dest_info.sentinel.?.eql(inst_info.sentinel.?, dest_info.pointee_type))17642 !dest_info.sentinel.?.eql(inst_info.sentinel.?, dest_info.pointee_type, target))
17519 break :p;17643 break :p;
1752017644
17521 const slice_ptr = try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty);17645 const slice_ptr = try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty);
...@@ -17528,11 +17652,11 @@ fn coerce(...@@ -17528,11 +17652,11 @@ fn coerce(
17528 const val = (try sema.resolveDefinedValue(block, inst_src, inst)) orelse break :float;17652 const val = (try sema.resolveDefinedValue(block, inst_src, inst)) orelse break :float;
1752917653
17530 if (val.floatHasFraction()) {17654 if (val.floatHasFraction()) {
17531 return sema.fail(block, inst_src, "fractional component prevents float value {} from coercion to type '{}'", .{ val.fmtValue(inst_ty), dest_ty });17655 return sema.fail(block, inst_src, "fractional component prevents float value {} from coercion to type '{}'", .{ val.fmtValue(inst_ty, target), dest_ty.fmt(target) });
17532 }17656 }
17533 const result_val = val.floatToInt(sema.arena, inst_ty, dest_ty, target) catch |err| switch (err) {17657 const result_val = val.floatToInt(sema.arena, inst_ty, dest_ty, target) catch |err| switch (err) {
17534 error.FloatCannotFit => {17658 error.FloatCannotFit => {
17535 return sema.fail(block, inst_src, "integer value {d} cannot be stored in type '{}'", .{ std.math.floor(val.toFloat(f64)), dest_ty });17659 return sema.fail(block, inst_src, "integer value {d} cannot be stored in type '{}'", .{ std.math.floor(val.toFloat(f64)), dest_ty.fmt(target) });
17536 },17660 },
17537 else => |e| return e,17661 else => |e| return e,
17538 };17662 };
...@@ -17542,7 +17666,7 @@ fn coerce(...@@ -17542,7 +17666,7 @@ fn coerce(
17542 if (try sema.resolveDefinedValue(block, inst_src, inst)) |val| {17666 if (try sema.resolveDefinedValue(block, inst_src, inst)) |val| {
17543 // comptime known integer to other number17667 // comptime known integer to other number
17544 if (!val.intFitsInType(dest_ty, target)) {17668 if (!val.intFitsInType(dest_ty, target)) {
17545 return sema.fail(block, inst_src, "type {} cannot represent integer value {}", .{ dest_ty, val.fmtValue(inst_ty) });17669 return sema.fail(block, inst_src, "type {} cannot represent integer value {}", .{ dest_ty.fmt(target), val.fmtValue(inst_ty, target) });
17546 }17670 }
17547 return try sema.addConstant(dest_ty, val);17671 return try sema.addConstant(dest_ty, val);
17548 }17672 }
...@@ -17572,12 +17696,12 @@ fn coerce(...@@ -17572,12 +17696,12 @@ fn coerce(
17572 .Float => {17696 .Float => {
17573 if (try sema.resolveDefinedValue(block, inst_src, inst)) |val| {17697 if (try sema.resolveDefinedValue(block, inst_src, inst)) |val| {
17574 const result_val = try val.floatCast(sema.arena, dest_ty, target);17698 const result_val = try val.floatCast(sema.arena, dest_ty, target);
17575 if (!val.eql(result_val, dest_ty)) {17699 if (!val.eql(result_val, dest_ty, target)) {
17576 return sema.fail(17700 return sema.fail(
17577 block,17701 block,
17578 inst_src,17702 inst_src,
17579 "type {} cannot represent float value {}",17703 "type {} cannot represent float value {}",
17580 .{ dest_ty, val.fmtValue(inst_ty) },17704 .{ dest_ty.fmt(target), val.fmtValue(inst_ty, target) },
17581 );17705 );
17582 }17706 }
17583 return try sema.addConstant(dest_ty, result_val);17707 return try sema.addConstant(dest_ty, result_val);
...@@ -17596,12 +17720,12 @@ fn coerce(...@@ -17596,12 +17720,12 @@ fn coerce(
17596 const result_val = try val.intToFloat(sema.arena, inst_ty, dest_ty, target);17720 const result_val = try val.intToFloat(sema.arena, inst_ty, dest_ty, target);
17597 // TODO implement this compile error17721 // TODO implement this compile error
17598 //const int_again_val = try result_val.floatToInt(sema.arena, inst_ty);17722 //const int_again_val = try result_val.floatToInt(sema.arena, inst_ty);
17599 //if (!int_again_val.eql(val, inst_ty)) {17723 //if (!int_again_val.eql(val, inst_ty, target)) {
17600 // return sema.fail(17724 // return sema.fail(
17601 // block,17725 // block,
17602 // inst_src,17726 // inst_src,
17603 // "type {} cannot represent integer value {}",17727 // "type {} cannot represent integer value {}",
17604 // .{ dest_ty, val },17728 // .{ dest_ty.fmt(target), val },
17605 // );17729 // );
17606 //}17730 //}
17607 return try sema.addConstant(dest_ty, result_val);17731 return try sema.addConstant(dest_ty, result_val);
...@@ -17622,7 +17746,7 @@ fn coerce(...@@ -17622,7 +17746,7 @@ fn coerce(
17622 block,17746 block,
17623 inst_src,17747 inst_src,
17624 "enum '{}' has no field named '{s}'",17748 "enum '{}' has no field named '{s}'",
17625 .{ dest_ty, bytes },17749 .{ dest_ty.fmt(target), bytes },
17626 );17750 );
17627 errdefer msg.destroy(sema.gpa);17751 errdefer msg.destroy(sema.gpa);
17628 try sema.mod.errNoteNonLazy(17752 try sema.mod.errNoteNonLazy(
...@@ -17643,7 +17767,7 @@ fn coerce(...@@ -17643,7 +17767,7 @@ fn coerce(
17643 .Union => blk: {17767 .Union => blk: {
17644 // union to its own tag type17768 // union to its own tag type
17645 const union_tag_ty = inst_ty.unionTagType() orelse break :blk;17769 const union_tag_ty = inst_ty.unionTagType() orelse break :blk;
17646 if (union_tag_ty.eql(dest_ty)) {17770 if (union_tag_ty.eql(dest_ty, target)) {
17647 return sema.unionToTag(block, dest_ty, inst, inst_src);17771 return sema.unionToTag(block, dest_ty, inst, inst_src);
17648 }17772 }
17649 },17773 },
...@@ -17743,7 +17867,7 @@ fn coerce(...@@ -17743,7 +17867,7 @@ fn coerce(
17743 return sema.addConstUndef(dest_ty);17867 return sema.addConstUndef(dest_ty);
17744 }17868 }
1774517869
17746 return sema.fail(block, inst_src, "expected {}, found {}", .{ dest_ty, inst_ty });17870 return sema.fail(block, inst_src, "expected {}, found {}", .{ dest_ty.fmt(target), inst_ty.fmt(target) });
17747}17871}
1774817872
17749const InMemoryCoercionResult = enum {17873const InMemoryCoercionResult = enum {
...@@ -17772,7 +17896,7 @@ fn coerceInMemoryAllowed(...@@ -17772,7 +17896,7 @@ fn coerceInMemoryAllowed(
17772 dest_src: LazySrcLoc,17896 dest_src: LazySrcLoc,
17773 src_src: LazySrcLoc,17897 src_src: LazySrcLoc,
17774) CompileError!InMemoryCoercionResult {17898) CompileError!InMemoryCoercionResult {
17775 if (dest_ty.eql(src_ty))17899 if (dest_ty.eql(src_ty, target))
17776 return .ok;17900 return .ok;
1777717901
17778 // Pointers / Pointer-like Optionals17902 // Pointers / Pointer-like Optionals
...@@ -17823,7 +17947,7 @@ fn coerceInMemoryAllowed(...@@ -17823,7 +17947,7 @@ fn coerceInMemoryAllowed(
17823 }17947 }
17824 const ok_sent = dest_info.sentinel == null or17948 const ok_sent = dest_info.sentinel == null or
17825 (src_info.sentinel != null and17949 (src_info.sentinel != null and
17826 dest_info.sentinel.?.eql(src_info.sentinel.?, dest_info.elem_type));17950 dest_info.sentinel.?.eql(src_info.sentinel.?, dest_info.elem_type, target));
17827 if (!ok_sent) {17951 if (!ok_sent) {
17828 return .no_match;17952 return .no_match;
17829 }17953 }
...@@ -18050,7 +18174,7 @@ fn coerceInMemoryAllowedPtrs(...@@ -18050,7 +18174,7 @@ fn coerceInMemoryAllowedPtrs(
1805018174
18051 const ok_sent = dest_info.sentinel == null or src_info.size == .C or18175 const ok_sent = dest_info.sentinel == null or src_info.size == .C or
18052 (src_info.sentinel != null and18176 (src_info.sentinel != null and
18053 dest_info.sentinel.?.eql(src_info.sentinel.?, dest_info.pointee_type));18177 dest_info.sentinel.?.eql(src_info.sentinel.?, dest_info.pointee_type, target));
18054 if (!ok_sent) {18178 if (!ok_sent) {
18055 return .no_match;18179 return .no_match;
18056 }18180 }
...@@ -18091,7 +18215,7 @@ fn coerceInMemoryAllowedPtrs(...@@ -18091,7 +18215,7 @@ fn coerceInMemoryAllowedPtrs(
18091 // resolved and we compare the alignment numerically.18215 // resolved and we compare the alignment numerically.
18092 alignment: {18216 alignment: {
18093 if (src_info.@"align" == 0 and dest_info.@"align" == 0 and18217 if (src_info.@"align" == 0 and dest_info.@"align" == 0 and
18094 dest_info.pointee_type.eql(src_info.pointee_type))18218 dest_info.pointee_type.eql(src_info.pointee_type, target))
18095 {18219 {
18096 break :alignment;18220 break :alignment;
18097 }18221 }
...@@ -18246,7 +18370,8 @@ fn obtainBitCastedVectorPtr(sema: *Sema, ptr: Air.Inst.Ref) ?Air.Inst.Ref {...@@ -18246,7 +18370,8 @@ fn obtainBitCastedVectorPtr(sema: *Sema, ptr: Air.Inst.Ref) ?Air.Inst.Ref {
18246 // We have a pointer-to-array and a pointer-to-vector. If the elements and18370 // We have a pointer-to-array and a pointer-to-vector. If the elements and
18247 // lengths match, return the result.18371 // lengths match, return the result.
18248 const vector_ty = sema.typeOf(prev_ptr).childType();18372 const vector_ty = sema.typeOf(prev_ptr).childType();
18249 if (array_ty.childType().eql(vector_ty.childType()) and18373 const target = sema.mod.getTarget();
18374 if (array_ty.childType().eql(vector_ty.childType(), target) and
18250 array_ty.arrayLen() == vector_ty.vectorLen())18375 array_ty.arrayLen() == vector_ty.vectorLen())
18251 {18376 {
18252 return prev_ptr;18377 return prev_ptr;
...@@ -18668,10 +18793,10 @@ fn beginComptimePtrLoad(...@@ -18668,10 +18793,10 @@ fn beginComptimePtrLoad(
18668 if (maybe_array_ty) |load_ty| {18793 if (maybe_array_ty) |load_ty| {
18669 // It's possible that we're loading a [N]T, in which case we'd like to slice18794 // It's possible that we're loading a [N]T, in which case we'd like to slice
18670 // the pointee array directly from our parent array.18795 // the pointee array directly from our parent array.
18671 if (load_ty.isArrayLike() and load_ty.childType().eql(elem_ty)) {18796 if (load_ty.isArrayLike() and load_ty.childType().eql(elem_ty, target)) {
18672 const N = try sema.usizeCast(block, src, load_ty.arrayLenIncludingSentinel());18797 const N = try sema.usizeCast(block, src, load_ty.arrayLenIncludingSentinel());
18673 deref.pointee = if (elem_ptr.index + N <= check_len) TypedValue{18798 deref.pointee = if (elem_ptr.index + N <= check_len) TypedValue{
18674 .ty = try Type.array(sema.arena, N, null, elem_ty),18799 .ty = try Type.array(sema.arena, N, null, elem_ty, target),
18675 .val = try array_tv.val.sliceArray(sema.arena, elem_ptr.index, elem_ptr.index + N),18800 .val = try array_tv.val.sliceArray(sema.arena, elem_ptr.index, elem_ptr.index + N),
18676 } else null;18801 } else null;
18677 break :blk deref;18802 break :blk deref;
...@@ -18807,11 +18932,11 @@ pub fn bitCastVal(...@@ -18807,11 +18932,11 @@ pub fn bitCastVal(
18807 new_ty: Type,18932 new_ty: Type,
18808 buffer_offset: usize,18933 buffer_offset: usize,
18809) !Value {18934) !Value {
18810 if (old_ty.eql(new_ty)) return val;18935 const target = sema.mod.getTarget();
18936 if (old_ty.eql(new_ty, target)) return val;
1881118937
18812 // For types with well-defined memory layouts, we serialize them a byte buffer,18938 // For types with well-defined memory layouts, we serialize them a byte buffer,
18813 // then deserialize to the new type.18939 // then deserialize to the new type.
18814 const target = sema.mod.getTarget();
18815 const abi_size = try sema.usizeCast(block, src, old_ty.abiSize(target));18940 const abi_size = try sema.usizeCast(block, src, old_ty.abiSize(target));
18816 const buffer = try sema.gpa.alloc(u8, abi_size);18941 const buffer = try sema.gpa.alloc(u8, abi_size);
18817 defer sema.gpa.free(buffer);18942 defer sema.gpa.free(buffer);
...@@ -18864,11 +18989,12 @@ fn coerceEnumToUnion(...@@ -18864,11 +18989,12 @@ fn coerceEnumToUnion(
18864 inst_src: LazySrcLoc,18989 inst_src: LazySrcLoc,
18865) !Air.Inst.Ref {18990) !Air.Inst.Ref {
18866 const inst_ty = sema.typeOf(inst);18991 const inst_ty = sema.typeOf(inst);
18992 const target = sema.mod.getTarget();
1886718993
18868 const tag_ty = union_ty.unionTagType() orelse {18994 const tag_ty = union_ty.unionTagType() orelse {
18869 const msg = msg: {18995 const msg = msg: {
18870 const msg = try sema.errMsg(block, inst_src, "expected {}, found {}", .{18996 const msg = try sema.errMsg(block, inst_src, "expected {}, found {}", .{
18871 union_ty, inst_ty,18997 union_ty.fmt(target), inst_ty.fmt(target),
18872 });18998 });
18873 errdefer msg.destroy(sema.gpa);18999 errdefer msg.destroy(sema.gpa);
18874 try sema.errNote(block, union_ty_src, msg, "cannot coerce enum to untagged union", .{});19000 try sema.errNote(block, union_ty_src, msg, "cannot coerce enum to untagged union", .{});
...@@ -18881,10 +19007,10 @@ fn coerceEnumToUnion(...@@ -18881,10 +19007,10 @@ fn coerceEnumToUnion(
18881 const enum_tag = try sema.coerce(block, tag_ty, inst, inst_src);19007 const enum_tag = try sema.coerce(block, tag_ty, inst, inst_src);
18882 if (try sema.resolveDefinedValue(block, inst_src, enum_tag)) |val| {19008 if (try sema.resolveDefinedValue(block, inst_src, enum_tag)) |val| {
18883 const union_obj = union_ty.cast(Type.Payload.Union).?.data;19009 const union_obj = union_ty.cast(Type.Payload.Union).?.data;
18884 const field_index = union_obj.tag_ty.enumTagFieldIndex(val) orelse {19010 const field_index = union_obj.tag_ty.enumTagFieldIndex(val, target) orelse {
18885 const msg = msg: {19011 const msg = msg: {
18886 const msg = try sema.errMsg(block, inst_src, "union {} has no tag with value {}", .{19012 const msg = try sema.errMsg(block, inst_src, "union {} has no tag with value {}", .{
18887 union_ty, val.fmtValue(tag_ty),19013 union_ty.fmt(target), val.fmtValue(tag_ty, target),
18888 });19014 });
18889 errdefer msg.destroy(sema.gpa);19015 errdefer msg.destroy(sema.gpa);
18890 try sema.addDeclaredHereNote(msg, union_ty);19016 try sema.addDeclaredHereNote(msg, union_ty);
...@@ -18899,7 +19025,7 @@ fn coerceEnumToUnion(...@@ -18899,7 +19025,7 @@ fn coerceEnumToUnion(
18899 // also instead of 'union declared here' make it 'field "foo" declared here'.19025 // also instead of 'union declared here' make it 'field "foo" declared here'.
18900 const msg = msg: {19026 const msg = msg: {
18901 const msg = try sema.errMsg(block, inst_src, "coercion to union {} must initialize {} field", .{19027 const msg = try sema.errMsg(block, inst_src, "coercion to union {} must initialize {} field", .{
18902 union_ty, field_ty,19028 union_ty.fmt(target), field_ty.fmt(target),
18903 });19029 });
18904 errdefer msg.destroy(sema.gpa);19030 errdefer msg.destroy(sema.gpa);
18905 try sema.addDeclaredHereNote(msg, union_ty);19031 try sema.addDeclaredHereNote(msg, union_ty);
...@@ -18919,7 +19045,7 @@ fn coerceEnumToUnion(...@@ -18919,7 +19045,7 @@ fn coerceEnumToUnion(
18919 if (tag_ty.isNonexhaustiveEnum()) {19045 if (tag_ty.isNonexhaustiveEnum()) {
18920 const msg = msg: {19046 const msg = msg: {
18921 const msg = try sema.errMsg(block, inst_src, "runtime coercion to union {} from non-exhaustive enum", .{19047 const msg = try sema.errMsg(block, inst_src, "runtime coercion to union {} from non-exhaustive enum", .{
18922 union_ty,19048 union_ty.fmt(target),
18923 });19049 });
18924 errdefer msg.destroy(sema.gpa);19050 errdefer msg.destroy(sema.gpa);
18925 try sema.addDeclaredHereNote(msg, tag_ty);19051 try sema.addDeclaredHereNote(msg, tag_ty);
...@@ -18937,7 +19063,7 @@ fn coerceEnumToUnion(...@@ -18937,7 +19063,7 @@ fn coerceEnumToUnion(
18937 // instead of the "union declared here" hint19063 // instead of the "union declared here" hint
18938 const msg = msg: {19064 const msg = msg: {
18939 const msg = try sema.errMsg(block, inst_src, "runtime coercion to union {} which has non-void fields", .{19065 const msg = try sema.errMsg(block, inst_src, "runtime coercion to union {} which has non-void fields", .{
18940 union_ty,19066 union_ty.fmt(target),
18941 });19067 });
18942 errdefer msg.destroy(sema.gpa);19068 errdefer msg.destroy(sema.gpa);
18943 try sema.addDeclaredHereNote(msg, union_ty);19069 try sema.addDeclaredHereNote(msg, union_ty);
...@@ -19020,11 +19146,12 @@ fn coerceArrayLike(...@@ -19020,11 +19146,12 @@ fn coerceArrayLike(
19020 const inst_ty = sema.typeOf(inst);19146 const inst_ty = sema.typeOf(inst);
19021 const inst_len = inst_ty.arrayLen();19147 const inst_len = inst_ty.arrayLen();
19022 const dest_len = try sema.usizeCast(block, dest_ty_src, dest_ty.arrayLen());19148 const dest_len = try sema.usizeCast(block, dest_ty_src, dest_ty.arrayLen());
19149 const target = sema.mod.getTarget();
1902319150
19024 if (dest_len != inst_len) {19151 if (dest_len != inst_len) {
19025 const msg = msg: {19152 const msg = msg: {
19026 const msg = try sema.errMsg(block, inst_src, "expected {}, found {}", .{19153 const msg = try sema.errMsg(block, inst_src, "expected {}, found {}", .{
19027 dest_ty, inst_ty,19154 dest_ty.fmt(target), inst_ty.fmt(target),
19028 });19155 });
19029 errdefer msg.destroy(sema.gpa);19156 errdefer msg.destroy(sema.gpa);
19030 try sema.errNote(block, dest_ty_src, msg, "destination has length {d}", .{dest_len});19157 try sema.errNote(block, dest_ty_src, msg, "destination has length {d}", .{dest_len});
...@@ -19034,7 +19161,6 @@ fn coerceArrayLike(...@@ -19034,7 +19161,6 @@ fn coerceArrayLike(
19034 return sema.failWithOwnedErrorMsg(block, msg);19161 return sema.failWithOwnedErrorMsg(block, msg);
19035 }19162 }
1903619163
19037 const target = sema.mod.getTarget();
19038 const dest_elem_ty = dest_ty.childType();19164 const dest_elem_ty = dest_ty.childType();
19039 const inst_elem_ty = inst_ty.childType();19165 const inst_elem_ty = inst_ty.childType();
19040 const in_memory_result = try sema.coerceInMemoryAllowed(block, dest_elem_ty, inst_elem_ty, false, target, dest_ty_src, inst_src);19166 const in_memory_result = try sema.coerceInMemoryAllowed(block, dest_elem_ty, inst_elem_ty, false, target, dest_ty_src, inst_src);
...@@ -19092,11 +19218,12 @@ fn coerceTupleToArray(...@@ -19092,11 +19218,12 @@ fn coerceTupleToArray(
19092 const inst_ty = sema.typeOf(inst);19218 const inst_ty = sema.typeOf(inst);
19093 const inst_len = inst_ty.arrayLen();19219 const inst_len = inst_ty.arrayLen();
19094 const dest_len = try sema.usizeCast(block, dest_ty_src, dest_ty.arrayLen());19220 const dest_len = try sema.usizeCast(block, dest_ty_src, dest_ty.arrayLen());
19221 const target = sema.mod.getTarget();
1909519222
19096 if (dest_len != inst_len) {19223 if (dest_len != inst_len) {
19097 const msg = msg: {19224 const msg = msg: {
19098 const msg = try sema.errMsg(block, inst_src, "expected {}, found {}", .{19225 const msg = try sema.errMsg(block, inst_src, "expected {}, found {}", .{
19099 dest_ty, inst_ty,19226 dest_ty.fmt(target), inst_ty.fmt(target),
19100 });19227 });
19101 errdefer msg.destroy(sema.gpa);19228 errdefer msg.destroy(sema.gpa);
19102 try sema.errNote(block, dest_ty_src, msg, "destination has length {d}", .{dest_len});19229 try sema.errNote(block, dest_ty_src, msg, "destination has length {d}", .{dest_len});
...@@ -19149,7 +19276,8 @@ fn coerceTupleToSlicePtrs(...@@ -19149,7 +19276,8 @@ fn coerceTupleToSlicePtrs(
19149 const tuple_ty = sema.typeOf(ptr_tuple).childType();19276 const tuple_ty = sema.typeOf(ptr_tuple).childType();
19150 const tuple = try sema.analyzeLoad(block, tuple_src, ptr_tuple, tuple_src);19277 const tuple = try sema.analyzeLoad(block, tuple_src, ptr_tuple, tuple_src);
19151 const slice_info = slice_ty.ptrInfo().data;19278 const slice_info = slice_ty.ptrInfo().data;
19152 const array_ty = try Type.array(sema.arena, tuple_ty.structFieldCount(), slice_info.sentinel, slice_info.pointee_type);19279 const target = sema.mod.getTarget();
19280 const array_ty = try Type.array(sema.arena, tuple_ty.structFieldCount(), slice_info.sentinel, slice_info.pointee_type, target);
19153 const array_inst = try sema.coerceTupleToArray(block, array_ty, slice_ty_src, tuple, tuple_src);19281 const array_inst = try sema.coerceTupleToArray(block, array_ty, slice_ty_src, tuple, tuple_src);
19154 if (slice_info.@"align" != 0) {19282 if (slice_info.@"align" != 0) {
19155 return sema.fail(block, slice_ty_src, "TODO: override the alignment of the array decl we create here", .{});19283 return sema.fail(block, slice_ty_src, "TODO: override the alignment of the array decl we create here", .{});
...@@ -19398,10 +19526,11 @@ fn analyzeLoad(...@@ -19398,10 +19526,11 @@ fn analyzeLoad(
19398 ptr: Air.Inst.Ref,19526 ptr: Air.Inst.Ref,
19399 ptr_src: LazySrcLoc,19527 ptr_src: LazySrcLoc,
19400) CompileError!Air.Inst.Ref {19528) CompileError!Air.Inst.Ref {
19529 const target = sema.mod.getTarget();
19401 const ptr_ty = sema.typeOf(ptr);19530 const ptr_ty = sema.typeOf(ptr);
19402 const elem_ty = switch (ptr_ty.zigTypeTag()) {19531 const elem_ty = switch (ptr_ty.zigTypeTag()) {
19403 .Pointer => ptr_ty.childType(),19532 .Pointer => ptr_ty.childType(),
19404 else => return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ty}),19533 else => return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ty.fmt(target)}),
19405 };19534 };
19406 if (try sema.resolveDefinedValue(block, ptr_src, ptr)) |ptr_val| {19535 if (try sema.resolveDefinedValue(block, ptr_src, ptr)) |ptr_val| {
19407 if (try sema.pointerDeref(block, ptr_src, ptr_val, ptr_ty)) |elem_val| {19536 if (try sema.pointerDeref(block, ptr_src, ptr_val, ptr_ty)) |elem_val| {
...@@ -19440,7 +19569,8 @@ fn analyzeSliceLen(...@@ -19440,7 +19569,8 @@ fn analyzeSliceLen(
19440 if (slice_val.isUndef()) {19569 if (slice_val.isUndef()) {
19441 return sema.addConstUndef(Type.usize);19570 return sema.addConstUndef(Type.usize);
19442 }19571 }
19443 return sema.addIntUnsigned(Type.usize, slice_val.sliceLen());19572 const target = sema.mod.getTarget();
19573 return sema.addIntUnsigned(Type.usize, slice_val.sliceLen(target));
19444 }19574 }
19445 try sema.requireRuntimeBlock(block, src);19575 try sema.requireRuntimeBlock(block, src);
19446 return block.addTyOp(.slice_len, Type.usize, slice_inst);19576 return block.addTyOp(.slice_len, Type.usize, slice_inst);
...@@ -19522,9 +19652,10 @@ fn analyzeSlice(...@@ -19522,9 +19652,10 @@ fn analyzeSlice(
19522 // Slice expressions can operate on a variable whose type is an array. This requires19652 // Slice expressions can operate on a variable whose type is an array. This requires
19523 // the slice operand to be a pointer. In the case of a non-array, it will be a double pointer.19653 // the slice operand to be a pointer. In the case of a non-array, it will be a double pointer.
19524 const ptr_ptr_ty = sema.typeOf(ptr_ptr);19654 const ptr_ptr_ty = sema.typeOf(ptr_ptr);
19655 const target = sema.mod.getTarget();
19525 const ptr_ptr_child_ty = switch (ptr_ptr_ty.zigTypeTag()) {19656 const ptr_ptr_child_ty = switch (ptr_ptr_ty.zigTypeTag()) {
19526 .Pointer => ptr_ptr_ty.elemType(),19657 .Pointer => ptr_ptr_ty.elemType(),
19527 else => return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ptr_ty}),19658 else => return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ptr_ty.fmt(target)}),
19528 };19659 };
1952919660
19530 var array_ty = ptr_ptr_child_ty;19661 var array_ty = ptr_ptr_child_ty;
...@@ -19564,7 +19695,7 @@ fn analyzeSlice(...@@ -19564,7 +19695,7 @@ fn analyzeSlice(
19564 elem_ty = ptr_ptr_child_ty.childType();19695 elem_ty = ptr_ptr_child_ty.childType();
19565 },19696 },
19566 },19697 },
19567 else => return sema.fail(block, ptr_src, "slice of non-array type '{}'", .{ptr_ptr_child_ty}),19698 else => return sema.fail(block, ptr_src, "slice of non-array type '{}'", .{ptr_ptr_child_ty.fmt(target)}),
19568 }19699 }
1956919700
19570 const ptr = if (slice_ty.isSlice())19701 const ptr = if (slice_ty.isSlice())
...@@ -19587,7 +19718,7 @@ fn analyzeSlice(...@@ -19587,7 +19718,7 @@ fn analyzeSlice(
19587 if (!end_is_len) {19718 if (!end_is_len) {
19588 const end = try sema.coerce(block, Type.usize, uncasted_end_opt, end_src);19719 const end = try sema.coerce(block, Type.usize, uncasted_end_opt, end_src);
19589 if (try sema.resolveMaybeUndefVal(block, end_src, end)) |end_val| {19720 if (try sema.resolveMaybeUndefVal(block, end_src, end)) |end_val| {
19590 if (end_val.compare(.gt, len_val, Type.usize)) {19721 if (end_val.compare(.gt, len_val, Type.usize, target)) {
19591 return sema.fail(19722 return sema.fail(
19592 block,19723 block,
19593 end_src,19724 end_src,
...@@ -19595,7 +19726,7 @@ fn analyzeSlice(...@@ -19595,7 +19726,7 @@ fn analyzeSlice(
19595 .{ end_val.fmtValue(Type.usize), len_val.fmtValue(Type.usize) },19726 .{ end_val.fmtValue(Type.usize), len_val.fmtValue(Type.usize) },
19596 );19727 );
19597 }19728 }
19598 if (end_val.eql(len_val, Type.usize)) {19729 if (end_val.eql(len_val, Type.usize, target)) {
19599 end_is_len = true;19730 end_is_len = true;
19600 }19731 }
19601 }19732 }
...@@ -19610,10 +19741,10 @@ fn analyzeSlice(...@@ -19610,10 +19741,10 @@ fn analyzeSlice(
19610 if (try sema.resolveDefinedValue(block, src, ptr_or_slice)) |slice_val| {19741 if (try sema.resolveDefinedValue(block, src, ptr_or_slice)) |slice_val| {
19611 var int_payload: Value.Payload.U64 = .{19742 var int_payload: Value.Payload.U64 = .{
19612 .base = .{ .tag = .int_u64 },19743 .base = .{ .tag = .int_u64 },
19613 .data = slice_val.sliceLen(),19744 .data = slice_val.sliceLen(target),
19614 };19745 };
19615 const slice_len_val = Value.initPayload(&int_payload.base);19746 const slice_len_val = Value.initPayload(&int_payload.base);
19616 if (end_val.compare(.gt, slice_len_val, Type.usize)) {19747 if (end_val.compare(.gt, slice_len_val, Type.usize, target)) {
19617 return sema.fail(19748 return sema.fail(
19618 block,19749 block,
19619 end_src,19750 end_src,
...@@ -19621,7 +19752,7 @@ fn analyzeSlice(...@@ -19621,7 +19752,7 @@ fn analyzeSlice(
19621 .{ end_val.fmtValue(Type.usize), slice_len_val.fmtValue(Type.usize) },19752 .{ end_val.fmtValue(Type.usize), slice_len_val.fmtValue(Type.usize) },
19622 );19753 );
19623 }19754 }
19624 if (end_val.eql(slice_len_val, Type.usize)) {19755 if (end_val.eql(slice_len_val, Type.usize, target)) {
19625 end_is_len = true;19756 end_is_len = true;
19626 }19757 }
19627 }19758 }
...@@ -19670,13 +19801,12 @@ fn analyzeSlice(...@@ -19670,13 +19801,12 @@ fn analyzeSlice(
1967019801
19671 const new_ptr_ty_info = sema.typeOf(new_ptr).ptrInfo().data;19802 const new_ptr_ty_info = sema.typeOf(new_ptr).ptrInfo().data;
19672 const new_allowzero = new_ptr_ty_info.@"allowzero" and sema.typeOf(ptr).ptrSize() != .C;19803 const new_allowzero = new_ptr_ty_info.@"allowzero" and sema.typeOf(ptr).ptrSize() != .C;
19673 const target = sema.mod.getTarget();
1967419804
19675 if (opt_new_len_val) |new_len_val| {19805 if (opt_new_len_val) |new_len_val| {
19676 const new_len_int = new_len_val.toUnsignedInt();19806 const new_len_int = new_len_val.toUnsignedInt(target);
1967719807
19678 const return_ty = try Type.ptr(sema.arena, target, .{19808 const return_ty = try Type.ptr(sema.arena, target, .{
19679 .pointee_type = try Type.array(sema.arena, new_len_int, sentinel, elem_ty),19809 .pointee_type = try Type.array(sema.arena, new_len_int, sentinel, elem_ty, target),
19680 .sentinel = null,19810 .sentinel = null,
19681 .@"align" = new_ptr_ty_info.@"align",19811 .@"align" = new_ptr_ty_info.@"align",
19682 .@"addrspace" = new_ptr_ty_info.@"addrspace",19812 .@"addrspace" = new_ptr_ty_info.@"addrspace",
...@@ -19746,6 +19876,7 @@ fn cmpNumeric(...@@ -19746,6 +19876,7 @@ fn cmpNumeric(
1974619876
19747 const lhs_ty_tag = lhs_ty.zigTypeTag();19877 const lhs_ty_tag = lhs_ty.zigTypeTag();
19748 const rhs_ty_tag = rhs_ty.zigTypeTag();19878 const rhs_ty_tag = rhs_ty.zigTypeTag();
19879 const target = sema.mod.getTarget();
1974919880
19750 const runtime_src: LazySrcLoc = src: {19881 const runtime_src: LazySrcLoc = src: {
19751 if (try sema.resolveMaybeUndefVal(block, lhs_src, lhs)) |lhs_val| {19882 if (try sema.resolveMaybeUndefVal(block, lhs_src, lhs)) |lhs_val| {
...@@ -19760,7 +19891,7 @@ fn cmpNumeric(...@@ -19760,7 +19891,7 @@ fn cmpNumeric(
19760 return Air.Inst.Ref.bool_false;19891 return Air.Inst.Ref.bool_false;
19761 }19892 }
19762 }19893 }
19763 if (Value.compareHetero(lhs_val, op, rhs_val)) {19894 if (Value.compareHetero(lhs_val, op, rhs_val, target)) {
19764 return Air.Inst.Ref.bool_true;19895 return Air.Inst.Ref.bool_true;
19765 } else {19896 } else {
19766 return Air.Inst.Ref.bool_false;19897 return Air.Inst.Ref.bool_false;
...@@ -19789,7 +19920,6 @@ fn cmpNumeric(...@@ -19789,7 +19920,6 @@ fn cmpNumeric(
19789 .Float, .ComptimeFloat => true,19920 .Float, .ComptimeFloat => true,
19790 else => false,19921 else => false,
19791 };19922 };
19792 const target = sema.mod.getTarget();
19793 if (lhs_is_float and rhs_is_float) {19923 if (lhs_is_float and rhs_is_float) {
19794 // Implicit cast the smaller one to the larger one.19924 // Implicit cast the smaller one to the larger one.
19795 const dest_ty = x: {19925 const dest_ty = x: {
...@@ -19846,7 +19976,7 @@ fn cmpNumeric(...@@ -19846,7 +19976,7 @@ fn cmpNumeric(
19846 }19976 }
19847 if (lhs_is_float) {19977 if (lhs_is_float) {
19848 var bigint_space: Value.BigIntSpace = undefined;19978 var bigint_space: Value.BigIntSpace = undefined;
19849 var bigint = try lhs_val.toBigInt(&bigint_space).toManaged(sema.gpa);19979 var bigint = try lhs_val.toBigInt(&bigint_space, target).toManaged(sema.gpa);
19850 defer bigint.deinit();19980 defer bigint.deinit();
19851 if (lhs_val.floatHasFraction()) {19981 if (lhs_val.floatHasFraction()) {
19852 switch (op) {19982 switch (op) {
...@@ -19892,7 +20022,7 @@ fn cmpNumeric(...@@ -19892,7 +20022,7 @@ fn cmpNumeric(
19892 }20022 }
19893 if (rhs_is_float) {20023 if (rhs_is_float) {
19894 var bigint_space: Value.BigIntSpace = undefined;20024 var bigint_space: Value.BigIntSpace = undefined;
19895 var bigint = try rhs_val.toBigInt(&bigint_space).toManaged(sema.gpa);20025 var bigint = try rhs_val.toBigInt(&bigint_space, target).toManaged(sema.gpa);
19896 defer bigint.deinit();20026 defer bigint.deinit();
19897 if (rhs_val.floatHasFraction()) {20027 if (rhs_val.floatHasFraction()) {
19898 switch (op) {20028 switch (op) {
...@@ -19950,6 +20080,7 @@ fn cmpVector(...@@ -19950,6 +20080,7 @@ fn cmpVector(
19950 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);20080 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);
1995120081
19952 const result_ty = try Type.vector(sema.arena, lhs_ty.vectorLen(), Type.@"bool");20082 const result_ty = try Type.vector(sema.arena, lhs_ty.vectorLen(), Type.@"bool");
20083 const target = sema.mod.getTarget();
1995320084
19954 const runtime_src: LazySrcLoc = src: {20085 const runtime_src: LazySrcLoc = src: {
19955 if (try sema.resolveMaybeUndefVal(block, lhs_src, lhs)) |lhs_val| {20086 if (try sema.resolveMaybeUndefVal(block, lhs_src, lhs)) |lhs_val| {
...@@ -19957,7 +20088,7 @@ fn cmpVector(...@@ -19957,7 +20088,7 @@ fn cmpVector(
19957 if (lhs_val.isUndef() or rhs_val.isUndef()) {20088 if (lhs_val.isUndef() or rhs_val.isUndef()) {
19958 return sema.addConstUndef(result_ty);20089 return sema.addConstUndef(result_ty);
19959 }20090 }
19960 const cmp_val = try lhs_val.compareVector(op, rhs_val, lhs_ty, sema.arena);20091 const cmp_val = try lhs_val.compareVector(op, rhs_val, lhs_ty, sema.arena, target);
19961 return sema.addConstant(result_ty, cmp_val);20092 return sema.addConstant(result_ty, cmp_val);
19962 } else {20093 } else {
19963 break :src rhs_src;20094 break :src rhs_src;
...@@ -20108,7 +20239,7 @@ fn resolvePeerTypes(...@@ -20108,7 +20239,7 @@ fn resolvePeerTypes(
20108 const candidate_ty_tag = try candidate_ty.zigTypeTagOrPoison();20239 const candidate_ty_tag = try candidate_ty.zigTypeTagOrPoison();
20109 const chosen_ty_tag = try chosen_ty.zigTypeTagOrPoison();20240 const chosen_ty_tag = try chosen_ty.zigTypeTagOrPoison();
2011020241
20111 if (candidate_ty.eql(chosen_ty))20242 if (candidate_ty.eql(chosen_ty, target))
20112 continue;20243 continue;
2011320244
20114 switch (candidate_ty_tag) {20245 switch (candidate_ty_tag) {
...@@ -20522,14 +20653,17 @@ fn resolvePeerTypes(...@@ -20522,14 +20653,17 @@ fn resolvePeerTypes(
20522 );20653 );
2052320654
20524 const msg = msg: {20655 const msg = msg: {
20525 const msg = try sema.errMsg(block, src, "incompatible types: '{}' and '{}'", .{ chosen_ty, candidate_ty });20656 const msg = try sema.errMsg(block, src, "incompatible types: '{}' and '{}'", .{
20657 chosen_ty.fmt(target),
20658 candidate_ty.fmt(target),
20659 });
20526 errdefer msg.destroy(sema.gpa);20660 errdefer msg.destroy(sema.gpa);
2052720661
20528 if (chosen_src) |src_loc|20662 if (chosen_src) |src_loc|
20529 try sema.errNote(block, src_loc, msg, "type '{}' here", .{chosen_ty});20663 try sema.errNote(block, src_loc, msg, "type '{}' here", .{chosen_ty.fmt(target)});
2053020664
20531 if (candidate_src) |src_loc|20665 if (candidate_src) |src_loc|
20532 try sema.errNote(block, src_loc, msg, "type '{}' here", .{candidate_ty});20666 try sema.errNote(block, src_loc, msg, "type '{}' here", .{candidate_ty.fmt(target)});
2053320667
20534 break :msg msg;20668 break :msg msg;
20535 };20669 };
...@@ -20557,7 +20691,7 @@ fn resolvePeerTypes(...@@ -20557,7 +20691,7 @@ fn resolvePeerTypes(
20557 else20691 else
20558 new_ptr_ty;20692 new_ptr_ty;
20559 const set_ty = err_set_ty orelse return opt_ptr_ty;20693 const set_ty = err_set_ty orelse return opt_ptr_ty;
20560 return try Module.errorUnionType(sema.arena, set_ty, opt_ptr_ty);20694 return try Type.errorUnion(sema.arena, set_ty, opt_ptr_ty, target);
20561 }20695 }
2056220696
20563 if (seen_const) {20697 if (seen_const) {
...@@ -20573,7 +20707,7 @@ fn resolvePeerTypes(...@@ -20573,7 +20707,7 @@ fn resolvePeerTypes(
20573 else20707 else
20574 new_ptr_ty;20708 new_ptr_ty;
20575 const set_ty = err_set_ty orelse chosen_ty.errorUnionSet();20709 const set_ty = err_set_ty orelse chosen_ty.errorUnionSet();
20576 return try Module.errorUnionType(sema.arena, set_ty, opt_ptr_ty);20710 return try Type.errorUnion(sema.arena, set_ty, opt_ptr_ty, target);
20577 },20711 },
20578 .Pointer => {20712 .Pointer => {
20579 var info = chosen_ty.ptrInfo();20713 var info = chosen_ty.ptrInfo();
...@@ -20584,7 +20718,7 @@ fn resolvePeerTypes(...@@ -20584,7 +20718,7 @@ fn resolvePeerTypes(
20584 else20718 else
20585 new_ptr_ty;20719 new_ptr_ty;
20586 const set_ty = err_set_ty orelse return opt_ptr_ty;20720 const set_ty = err_set_ty orelse return opt_ptr_ty;
20587 return try Module.errorUnionType(sema.arena, set_ty, opt_ptr_ty);20721 return try Type.errorUnion(sema.arena, set_ty, opt_ptr_ty, target);
20588 },20722 },
20589 else => return chosen_ty,20723 else => return chosen_ty,
20590 }20724 }
...@@ -20596,16 +20730,16 @@ fn resolvePeerTypes(...@@ -20596,16 +20730,16 @@ fn resolvePeerTypes(
20596 else => try Type.optional(sema.arena, chosen_ty),20730 else => try Type.optional(sema.arena, chosen_ty),
20597 };20731 };
20598 const set_ty = err_set_ty orelse return opt_ty;20732 const set_ty = err_set_ty orelse return opt_ty;
20599 return try Module.errorUnionType(sema.arena, set_ty, opt_ty);20733 return try Type.errorUnion(sema.arena, set_ty, opt_ty, target);
20600 }20734 }
2060120735
20602 if (err_set_ty) |ty| switch (chosen_ty.zigTypeTag()) {20736 if (err_set_ty) |ty| switch (chosen_ty.zigTypeTag()) {
20603 .ErrorSet => return ty,20737 .ErrorSet => return ty,
20604 .ErrorUnion => {20738 .ErrorUnion => {
20605 const payload_ty = chosen_ty.errorUnionPayload();20739 const payload_ty = chosen_ty.errorUnionPayload();
20606 return try Module.errorUnionType(sema.arena, ty, payload_ty);20740 return try Type.errorUnion(sema.arena, ty, payload_ty, target);
20607 },20741 },
20608 else => return try Module.errorUnionType(sema.arena, ty, chosen_ty),20742 else => return try Type.errorUnion(sema.arena, ty, chosen_ty, target),
20609 };20743 };
2061020744
20611 return chosen_ty;20745 return chosen_ty;
...@@ -20662,11 +20796,12 @@ fn resolveStructLayout(...@@ -20662,11 +20796,12 @@ fn resolveStructLayout(
20662) CompileError!void {20796) CompileError!void {
20663 const resolved_ty = try sema.resolveTypeFields(block, src, ty);20797 const resolved_ty = try sema.resolveTypeFields(block, src, ty);
20664 if (resolved_ty.castTag(.@"struct")) |payload| {20798 if (resolved_ty.castTag(.@"struct")) |payload| {
20799 const target = sema.mod.getTarget();
20665 const struct_obj = payload.data;20800 const struct_obj = payload.data;
20666 switch (struct_obj.status) {20801 switch (struct_obj.status) {
20667 .none, .have_field_types => {},20802 .none, .have_field_types => {},
20668 .field_types_wip, .layout_wip => {20803 .field_types_wip, .layout_wip => {
20669 return sema.fail(block, src, "struct {} depends on itself", .{ty});20804 return sema.fail(block, src, "struct {} depends on itself", .{ty.fmt(target)});
20670 },20805 },
20671 .have_layout, .fully_resolved_wip, .fully_resolved => return,20806 .have_layout, .fully_resolved_wip, .fully_resolved => return,
20672 }20807 }
...@@ -20694,10 +20829,11 @@ fn resolveUnionLayout(...@@ -20694,10 +20829,11 @@ fn resolveUnionLayout(
20694) CompileError!void {20829) CompileError!void {
20695 const resolved_ty = try sema.resolveTypeFields(block, src, ty);20830 const resolved_ty = try sema.resolveTypeFields(block, src, ty);
20696 const union_obj = resolved_ty.cast(Type.Payload.Union).?.data;20831 const union_obj = resolved_ty.cast(Type.Payload.Union).?.data;
20832 const target = sema.mod.getTarget();
20697 switch (union_obj.status) {20833 switch (union_obj.status) {
20698 .none, .have_field_types => {},20834 .none, .have_field_types => {},
20699 .field_types_wip, .layout_wip => {20835 .field_types_wip, .layout_wip => {
20700 return sema.fail(block, src, "union {} depends on itself", .{ty});20836 return sema.fail(block, src, "union {} depends on itself", .{ty.fmt(target)});
20701 },20837 },
20702 .have_layout, .fully_resolved_wip, .fully_resolved => return,20838 .have_layout, .fully_resolved_wip, .fully_resolved => return,
20703 }20839 }
...@@ -20828,10 +20964,11 @@ fn resolveTypeFieldsStruct(...@@ -20828,10 +20964,11 @@ fn resolveTypeFieldsStruct(
20828 ty: Type,20964 ty: Type,
20829 struct_obj: *Module.Struct,20965 struct_obj: *Module.Struct,
20830) CompileError!void {20966) CompileError!void {
20967 const target = sema.mod.getTarget();
20831 switch (struct_obj.status) {20968 switch (struct_obj.status) {
20832 .none => {},20969 .none => {},
20833 .field_types_wip => {20970 .field_types_wip => {
20834 return sema.fail(block, src, "struct {} depends on itself", .{ty});20971 return sema.fail(block, src, "struct {} depends on itself", .{ty.fmt(target)});
20835 },20972 },
20836 .have_field_types,20973 .have_field_types,
20837 .have_layout,20974 .have_layout,
...@@ -20858,10 +20995,11 @@ fn resolveTypeFieldsUnion(...@@ -20858,10 +20995,11 @@ fn resolveTypeFieldsUnion(
20858 ty: Type,20995 ty: Type,
20859 union_obj: *Module.Union,20996 union_obj: *Module.Union,
20860) CompileError!void {20997) CompileError!void {
20998 const target = sema.mod.getTarget();
20861 switch (union_obj.status) {20999 switch (union_obj.status) {
20862 .none => {},21000 .none => {},
20863 .field_types_wip => {21001 .field_types_wip => {
20864 return sema.fail(block, src, "union {} depends on itself", .{ty});21002 return sema.fail(block, src, "union {} depends on itself", .{ty.fmt(target)});
20865 },21003 },
20866 .have_field_types,21004 .have_field_types,
20867 .have_layout,21005 .have_layout,
...@@ -21218,6 +21356,8 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {...@@ -21218,6 +21356,8 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
21218 enum_field_names = &union_obj.tag_ty.castTag(.enum_simple).?.data.fields;21356 enum_field_names = &union_obj.tag_ty.castTag(.enum_simple).?.data.fields;
21219 }21357 }
2122021358
21359 const target = sema.mod.getTarget();
21360
21221 const bits_per_field = 4;21361 const bits_per_field = 4;
21222 const fields_per_u32 = 32 / bits_per_field;21362 const fields_per_u32 = 32 / bits_per_field;
21223 const bit_bags_count = std.math.divCeil(usize, fields_len, fields_per_u32) catch unreachable;21363 const bit_bags_count = std.math.divCeil(usize, fields_len, fields_per_u32) catch unreachable;
...@@ -21275,16 +21415,22 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {...@@ -21275,16 +21415,22 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
21275 // This puts the memory into the union arena, not the enum arena, but21415 // This puts the memory into the union arena, not the enum arena, but
21276 // it is OK since they share the same lifetime.21416 // it is OK since they share the same lifetime.
21277 const copied_val = try val.copy(decl_arena_allocator);21417 const copied_val = try val.copy(decl_arena_allocator);
21278 map.putAssumeCapacityContext(copied_val, {}, .{ .ty = int_tag_ty });21418 map.putAssumeCapacityContext(copied_val, {}, .{
21419 .ty = int_tag_ty,
21420 .target = target,
21421 });
21279 } else {21422 } else {
21280 const val = if (last_tag_val) |val|21423 const val = if (last_tag_val) |val|
21281 try val.intAdd(Value.one, int_tag_ty, sema.arena)21424 try val.intAdd(Value.one, int_tag_ty, sema.arena, target)
21282 else21425 else
21283 Value.zero;21426 Value.zero;
21284 last_tag_val = val;21427 last_tag_val = val;
2128521428
21286 const copied_val = try val.copy(decl_arena_allocator);21429 const copied_val = try val.copy(decl_arena_allocator);
21287 map.putAssumeCapacityContext(copied_val, {}, .{ .ty = int_tag_ty });21430 map.putAssumeCapacityContext(copied_val, {}, .{
21431 .ty = int_tag_ty,
21432 .target = target,
21433 });
21288 }21434 }
21289 }21435 }
2129021436
...@@ -21359,7 +21505,10 @@ fn generateUnionTagTypeNumbered(...@@ -21359,7 +21505,10 @@ fn generateUnionTagTypeNumbered(
21359 };21505 };
21360 // Here we pre-allocate the maps using the decl arena.21506 // Here we pre-allocate the maps using the decl arena.
21361 try enum_obj.fields.ensureTotalCapacity(new_decl_arena_allocator, fields_len);21507 try enum_obj.fields.ensureTotalCapacity(new_decl_arena_allocator, fields_len);
21362 try enum_obj.values.ensureTotalCapacityContext(new_decl_arena_allocator, fields_len, .{ .ty = int_ty });21508 try enum_obj.values.ensureTotalCapacityContext(new_decl_arena_allocator, fields_len, .{
21509 .ty = int_ty,
21510 .target = sema.mod.getTarget(),
21511 });
21363 try new_decl.finalizeNewArena(&new_decl_arena);21512 try new_decl.finalizeNewArena(&new_decl_arena);
21364 return enum_ty;21513 return enum_ty;
21365}21514}
...@@ -21962,7 +22111,7 @@ fn pointerDeref(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, ptr...@@ -21962,7 +22111,7 @@ fn pointerDeref(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, ptr
21962 // The type is not in-memory coercible or the direct dereference failed, so it must22111 // The type is not in-memory coercible or the direct dereference failed, so it must
21963 // be bitcast according to the pointer type we are performing the load through.22112 // be bitcast according to the pointer type we are performing the load through.
21964 if (!load_ty.hasWellDefinedLayout())22113 if (!load_ty.hasWellDefinedLayout())
21965 return sema.fail(block, src, "comptime dereference requires {} to have a well-defined layout, but it does not.", .{load_ty});22114 return sema.fail(block, src, "comptime dereference requires {} to have a well-defined layout, but it does not.", .{load_ty.fmt(target)});
2196622115
21967 const load_sz = try sema.typeAbiSize(block, src, load_ty);22116 const load_sz = try sema.typeAbiSize(block, src, load_ty);
2196822117
...@@ -21977,11 +22126,11 @@ fn pointerDeref(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, ptr...@@ -21977,11 +22126,11 @@ fn pointerDeref(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, ptr
21977 if (deref.ty_without_well_defined_layout) |bad_ty| {22126 if (deref.ty_without_well_defined_layout) |bad_ty| {
21978 // We got no parent for bit-casting, or the parent we got was too small. Either way, the problem22127 // We got no parent for bit-casting, or the parent we got was too small. Either way, the problem
21979 // is that some type we encountered when de-referencing does not have a well-defined layout.22128 // is that some type we encountered when de-referencing does not have a well-defined layout.
21980 return sema.fail(block, src, "comptime dereference requires {} to have a well-defined layout, but it does not.", .{bad_ty});22129 return sema.fail(block, src, "comptime dereference requires {} to have a well-defined layout, but it does not.", .{bad_ty.fmt(target)});
21981 } else {22130 } else {
21982 // If all encountered types had well-defined layouts, the parent is the root decl and it just22131 // If all encountered types had well-defined layouts, the parent is the root decl and it just
21983 // wasn't big enough for the load.22132 // wasn't big enough for the load.
21984 return sema.fail(block, src, "dereference of {} exceeds bounds of containing decl of type {}", .{ ptr_ty, deref.parent.?.tv.ty });22133 return sema.fail(block, src, "dereference of {} exceeds bounds of containing decl of type {}", .{ ptr_ty.fmt(target), deref.parent.?.tv.ty.fmt(target) });
21985 }22134 }
21986}22135}
2198722136
...@@ -22344,7 +22493,8 @@ fn anonStructFieldIndex(...@@ -22344,7 +22493,8 @@ fn anonStructFieldIndex(
22344 return @intCast(u32, i);22493 return @intCast(u32, i);
22345 }22494 }
22346 }22495 }
22496 const target = sema.mod.getTarget();
22347 return sema.fail(block, field_src, "anonymous struct {} has no such field '{s}'", .{22497 return sema.fail(block, field_src, "anonymous struct {} has no such field '{s}'", .{
22348 struct_ty, field_name,22498 struct_ty.fmt(target), field_name,
22349 });22499 });
22350}22500}
src/TypedValue.zig+35-22
...@@ -3,6 +3,7 @@ const Type = @import("type.zig").Type;...@@ -3,6 +3,7 @@ const Type = @import("type.zig").Type;
3const Value = @import("value.zig").Value;3const Value = @import("value.zig").Value;
4const Allocator = std.mem.Allocator;4const Allocator = std.mem.Allocator;
5const TypedValue = @This();5const TypedValue = @This();
6const Target = std.Target;
67
7ty: Type,8ty: Type,
8val: Value,9val: Value,
...@@ -30,13 +31,13 @@ pub fn copy(self: TypedValue, arena: Allocator) error{OutOfMemory}!TypedValue {...@@ -30,13 +31,13 @@ pub fn copy(self: TypedValue, arena: Allocator) error{OutOfMemory}!TypedValue {
30 };31 };
31}32}
3233
33pub fn eql(a: TypedValue, b: TypedValue) bool {34pub fn eql(a: TypedValue, b: TypedValue, target: std.Target) bool {
34 if (!a.ty.eql(b.ty)) return false;35 if (!a.ty.eql(b.ty, target)) return false;
35 return a.val.eql(b.val, a.ty);36 return a.val.eql(b.val, a.ty, target);
36}37}
3738
38pub fn hash(tv: TypedValue, hasher: *std.hash.Wyhash) void {39pub fn hash(tv: TypedValue, hasher: *std.hash.Wyhash, target: std.Target) void {
39 return tv.val.hash(tv.ty, hasher);40 return tv.val.hash(tv.ty, hasher, target);
40}41}
4142
42pub fn enumToInt(tv: TypedValue, buffer: *Value.Payload.U64) Value {43pub fn enumToInt(tv: TypedValue, buffer: *Value.Payload.U64) Value {
...@@ -45,21 +46,28 @@ pub fn enumToInt(tv: TypedValue, buffer: *Value.Payload.U64) Value {...@@ -45,21 +46,28 @@ pub fn enumToInt(tv: TypedValue, buffer: *Value.Payload.U64) Value {
4546
46const max_aggregate_items = 100;47const max_aggregate_items = 100;
4748
48pub fn format(49const FormatContext = struct {
49 tv: TypedValue,50 tv: TypedValue,
51 target: Target,
52};
53
54pub fn format(
55 ctx: FormatContext,
50 comptime fmt: []const u8,56 comptime fmt: []const u8,
51 options: std.fmt.FormatOptions,57 options: std.fmt.FormatOptions,
52 writer: anytype,58 writer: anytype,
53) !void {59) !void {
60 _ = options;
54 comptime std.debug.assert(fmt.len == 0);61 comptime std.debug.assert(fmt.len == 0);
55 return tv.print(options, writer, 3);62 return ctx.tv.print(writer, 3, ctx.target);
56}63}
5764
65/// Prints the Value according to the Type, not according to the Value Tag.
58pub fn print(66pub fn print(
59 tv: TypedValue,67 tv: TypedValue,
60 options: std.fmt.FormatOptions,
61 writer: anytype,68 writer: anytype,
62 level: u8,69 level: u8,
70 target: std.Target,
63) @TypeOf(writer).Error!void {71) @TypeOf(writer).Error!void {
64 var val = tv.val;72 var val = tv.val;
65 var ty = tv.ty;73 var ty = tv.ty;
...@@ -148,7 +156,7 @@ pub fn print(...@@ -148,7 +156,7 @@ pub fn print(
148 try print(.{156 try print(.{
149 .ty = fields[i].ty,157 .ty = fields[i].ty,
150 .val = vals[i],158 .val = vals[i],
151 }, options, writer, level - 1);159 }, writer, level - 1, target);
152 }160 }
153 return writer.writeAll(" }");161 return writer.writeAll(" }");
154 } else {162 } else {
...@@ -162,7 +170,7 @@ pub fn print(...@@ -162,7 +170,7 @@ pub fn print(
162 try print(.{170 try print(.{
163 .ty = elem_ty,171 .ty = elem_ty,
164 .val = vals[i],172 .val = vals[i],
165 }, options, writer, level - 1);173 }, writer, level - 1, target);
166 }174 }
167 return writer.writeAll(" }");175 return writer.writeAll(" }");
168 }176 }
...@@ -177,12 +185,12 @@ pub fn print(...@@ -177,12 +185,12 @@ pub fn print(
177 try print(.{185 try print(.{
178 .ty = ty.unionTagType().?,186 .ty = ty.unionTagType().?,
179 .val = union_val.tag,187 .val = union_val.tag,
180 }, options, writer, level - 1);188 }, writer, level - 1, target);
181 try writer.writeAll(" = ");189 try writer.writeAll(" = ");
182 try print(.{190 try print(.{
183 .ty = ty.unionFieldType(union_val.tag),191 .ty = ty.unionFieldType(union_val.tag, target),
184 .val = union_val.val,192 .val = union_val.val,
185 }, options, writer, level - 1);193 }, writer, level - 1, target);
186194
187 return writer.writeAll(" }");195 return writer.writeAll(" }");
188 },196 },
...@@ -197,7 +205,7 @@ pub fn print(...@@ -197,7 +205,7 @@ pub fn print(
197 },205 },
198 .bool_true => return writer.writeAll("true"),206 .bool_true => return writer.writeAll("true"),
199 .bool_false => return writer.writeAll("false"),207 .bool_false => return writer.writeAll("false"),
200 .ty => return val.castTag(.ty).?.data.format("", options, writer),208 .ty => return val.castTag(.ty).?.data.print(writer, target),
201 .int_type => {209 .int_type => {
202 const int_type = val.castTag(.int_type).?.data;210 const int_type = val.castTag(.int_type).?.data;
203 return writer.print("{s}{d}", .{211 return writer.print("{s}{d}", .{
...@@ -205,10 +213,15 @@ pub fn print(...@@ -205,10 +213,15 @@ pub fn print(
205 int_type.bits,213 int_type.bits,
206 });214 });
207 },215 },
208 .int_u64 => return std.fmt.formatIntValue(val.castTag(.int_u64).?.data, "", options, writer),216 .int_u64 => return std.fmt.formatIntValue(val.castTag(.int_u64).?.data, "", .{}, writer),
209 .int_i64 => return std.fmt.formatIntValue(val.castTag(.int_i64).?.data, "", options, writer),217 .int_i64 => return std.fmt.formatIntValue(val.castTag(.int_i64).?.data, "", .{}, writer),
210 .int_big_positive => return writer.print("{}", .{val.castTag(.int_big_positive).?.asBigInt()}),218 .int_big_positive => return writer.print("{}", .{val.castTag(.int_big_positive).?.asBigInt()}),
211 .int_big_negative => return writer.print("{}", .{val.castTag(.int_big_negative).?.asBigInt()}),219 .int_big_negative => return writer.print("{}", .{val.castTag(.int_big_negative).?.asBigInt()}),
220 .lazy_align => {
221 const sub_ty = val.castTag(.lazy_align).?.data;
222 const x = sub_ty.abiAlignment(target);
223 return writer.print("{d}", .{x});
224 },
212 .function => return writer.print("(function '{s}')", .{val.castTag(.function).?.data.owner_decl.name}),225 .function => return writer.print("(function '{s}')", .{val.castTag(.function).?.data.owner_decl.name}),
213 .extern_fn => return writer.writeAll("(extern function)"),226 .extern_fn => return writer.writeAll("(extern function)"),
214 .variable => return writer.writeAll("(variable)"),227 .variable => return writer.writeAll("(variable)"),
...@@ -220,7 +233,7 @@ pub fn print(...@@ -220,7 +233,7 @@ pub fn print(
220 return print(.{233 return print(.{
221 .ty = decl.ty,234 .ty = decl.ty,
222 .val = decl.val,235 .val = decl.val,
223 }, options, writer, level - 1);236 }, writer, level - 1, target);
224 },237 },
225 .decl_ref => {238 .decl_ref => {
226 const decl = val.castTag(.decl_ref).?.data;239 const decl = val.castTag(.decl_ref).?.data;
...@@ -230,7 +243,7 @@ pub fn print(...@@ -230,7 +243,7 @@ pub fn print(
230 return print(.{243 return print(.{
231 .ty = decl.ty,244 .ty = decl.ty,
232 .val = decl.val,245 .val = decl.val,
233 }, options, writer, level - 1);246 }, writer, level - 1, target);
234 },247 },
235 .elem_ptr => {248 .elem_ptr => {
236 const elem_ptr = val.castTag(.elem_ptr).?.data;249 const elem_ptr = val.castTag(.elem_ptr).?.data;
...@@ -238,7 +251,7 @@ pub fn print(...@@ -238,7 +251,7 @@ pub fn print(
238 try print(.{251 try print(.{
239 .ty = elem_ptr.elem_ty,252 .ty = elem_ptr.elem_ty,
240 .val = elem_ptr.array_ptr,253 .val = elem_ptr.array_ptr,
241 }, options, writer, level - 1);254 }, writer, level - 1, target);
242 return writer.print("[{}]", .{elem_ptr.index});255 return writer.print("[{}]", .{elem_ptr.index});
243 },256 },
244 .field_ptr => {257 .field_ptr => {
...@@ -247,7 +260,7 @@ pub fn print(...@@ -247,7 +260,7 @@ pub fn print(
247 try print(.{260 try print(.{
248 .ty = field_ptr.container_ty,261 .ty = field_ptr.container_ty,
249 .val = field_ptr.container_ptr,262 .val = field_ptr.container_ptr,
250 }, options, writer, level - 1);263 }, writer, level - 1, target);
251264
252 if (field_ptr.container_ty.zigTypeTag() == .Struct) {265 if (field_ptr.container_ty.zigTypeTag() == .Struct) {
253 const field_name = field_ptr.container_ty.structFields().keys()[field_ptr.field_index];266 const field_name = field_ptr.container_ty.structFields().keys()[field_ptr.field_index];
...@@ -275,7 +288,7 @@ pub fn print(...@@ -275,7 +288,7 @@ pub fn print(
275 };288 };
276 while (i < max_aggregate_items) : (i += 1) {289 while (i < max_aggregate_items) : (i += 1) {
277 if (i != 0) try writer.writeAll(", ");290 if (i != 0) try writer.writeAll(", ");
278 try print(elem_tv, options, writer, level - 1);291 try print(elem_tv, writer, level - 1, target);
279 }292 }
280 return writer.writeAll(" }");293 return writer.writeAll(" }");
281 },294 },
...@@ -287,7 +300,7 @@ pub fn print(...@@ -287,7 +300,7 @@ pub fn print(
287 try print(.{300 try print(.{
288 .ty = ty.elemType2(),301 .ty = ty.elemType2(),
289 .val = ty.sentinel().?,302 .val = ty.sentinel().?,
290 }, options, writer, level - 1);303 }, writer, level - 1, target);
291 return writer.writeAll(" }");304 return writer.writeAll(" }");
292 },305 },
293 .slice => return writer.writeAll("(slice)"),306 .slice => return writer.writeAll("(slice)"),
src/arch/aarch64/CodeGen.zig+20-13
...@@ -796,7 +796,9 @@ fn addDbgInfoTypeReloc(self: *Self, ty: Type) !void {...@@ -796,7 +796,9 @@ fn addDbgInfoTypeReloc(self: *Self, ty: Type) !void {
796 const index = dbg_out.dbg_info.items.len;796 const index = dbg_out.dbg_info.items.len;
797 try dbg_out.dbg_info.resize(index + 4); // DW.AT.type, DW.FORM.ref4797 try dbg_out.dbg_info.resize(index + 4); // DW.AT.type, DW.FORM.ref4
798798
799 const gop = try dbg_out.dbg_info_type_relocs.getOrPut(self.gpa, ty);799 const gop = try dbg_out.dbg_info_type_relocs.getOrPutContext(self.gpa, ty, .{
800 .target = self.target.*,
801 });
800 if (!gop.found_existing) {802 if (!gop.found_existing) {
801 gop.value_ptr.* = .{803 gop.value_ptr.* = .{
802 .off = undefined,804 .off = undefined,
...@@ -835,8 +837,9 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {...@@ -835,8 +837,9 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
835 return self.next_stack_offset;837 return self.next_stack_offset;
836 }838 }
837839
840 const target = self.target.*;
838 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {841 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {
839 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty});842 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(target)});
840 };843 };
841 // TODO swap this for inst.ty.ptrAlign844 // TODO swap this for inst.ty.ptrAlign
842 const abi_align = elem_ty.abiAlignment(self.target.*);845 const abi_align = elem_ty.abiAlignment(self.target.*);
...@@ -845,8 +848,9 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {...@@ -845,8 +848,9 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
845848
846fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {849fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {
847 const elem_ty = self.air.typeOfIndex(inst);850 const elem_ty = self.air.typeOfIndex(inst);
851 const target = self.target.*;
848 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {852 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {
849 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty});853 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(target)});
850 };854 };
851 const abi_align = elem_ty.abiAlignment(self.target.*);855 const abi_align = elem_ty.abiAlignment(self.target.*);
852 if (abi_align > self.stack_align)856 if (abi_align > self.stack_align)
...@@ -1372,6 +1376,7 @@ fn binOp(...@@ -1372,6 +1376,7 @@ fn binOp(
1372 lhs_ty: Type,1376 lhs_ty: Type,
1373 rhs_ty: Type,1377 rhs_ty: Type,
1374) InnerError!MCValue {1378) InnerError!MCValue {
1379 const target = self.target.*;
1375 switch (tag) {1380 switch (tag) {
1376 // Arithmetic operations on integers and floats1381 // Arithmetic operations on integers and floats
1377 .add,1382 .add,
...@@ -1381,7 +1386,7 @@ fn binOp(...@@ -1381,7 +1386,7 @@ fn binOp(
1381 .Float => return self.fail("TODO binary operations on floats", .{}),1386 .Float => return self.fail("TODO binary operations on floats", .{}),
1382 .Vector => return self.fail("TODO binary operations on vectors", .{}),1387 .Vector => return self.fail("TODO binary operations on vectors", .{}),
1383 .Int => {1388 .Int => {
1384 assert(lhs_ty.eql(rhs_ty));1389 assert(lhs_ty.eql(rhs_ty, target));
1385 const int_info = lhs_ty.intInfo(self.target.*);1390 const int_info = lhs_ty.intInfo(self.target.*);
1386 if (int_info.bits <= 64) {1391 if (int_info.bits <= 64) {
1387 // Only say yes if the operation is1392 // Only say yes if the operation is
...@@ -1418,7 +1423,7 @@ fn binOp(...@@ -1418,7 +1423,7 @@ fn binOp(
1418 switch (lhs_ty.zigTypeTag()) {1423 switch (lhs_ty.zigTypeTag()) {
1419 .Vector => return self.fail("TODO binary operations on vectors", .{}),1424 .Vector => return self.fail("TODO binary operations on vectors", .{}),
1420 .Int => {1425 .Int => {
1421 assert(lhs_ty.eql(rhs_ty));1426 assert(lhs_ty.eql(rhs_ty, target));
1422 const int_info = lhs_ty.intInfo(self.target.*);1427 const int_info = lhs_ty.intInfo(self.target.*);
1423 if (int_info.bits <= 64) {1428 if (int_info.bits <= 64) {
1424 // TODO add optimisations for multiplication1429 // TODO add optimisations for multiplication
...@@ -1440,7 +1445,7 @@ fn binOp(...@@ -1440,7 +1445,7 @@ fn binOp(
1440 switch (lhs_ty.zigTypeTag()) {1445 switch (lhs_ty.zigTypeTag()) {
1441 .Vector => return self.fail("TODO binary operations on vectors", .{}),1446 .Vector => return self.fail("TODO binary operations on vectors", .{}),
1442 .Int => {1447 .Int => {
1443 assert(lhs_ty.eql(rhs_ty));1448 assert(lhs_ty.eql(rhs_ty, target));
1444 const int_info = lhs_ty.intInfo(self.target.*);1449 const int_info = lhs_ty.intInfo(self.target.*);
1445 if (int_info.bits <= 64) {1450 if (int_info.bits <= 64) {
1446 // TODO implement bitwise operations with immediates1451 // TODO implement bitwise operations with immediates
...@@ -2348,11 +2353,12 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {...@@ -2348,11 +2353,12 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
2348 const ty = self.air.typeOfIndex(inst);2353 const ty = self.air.typeOfIndex(inst);
23492354
2350 const result = self.args[arg_index];2355 const result = self.args[arg_index];
2356 const target = self.target.*;
2351 const mcv = switch (result) {2357 const mcv = switch (result) {
2352 // Copy registers to the stack2358 // Copy registers to the stack
2353 .register => |reg| blk: {2359 .register => |reg| blk: {
2354 const abi_size = math.cast(u32, ty.abiSize(self.target.*)) catch {2360 const abi_size = math.cast(u32, ty.abiSize(self.target.*)) catch {
2355 return self.fail("type '{}' too big to fit into stack frame", .{ty});2361 return self.fail("type '{}' too big to fit into stack frame", .{ty.fmt(target)});
2356 };2362 };
2357 const abi_align = ty.abiAlignment(self.target.*);2363 const abi_align = ty.abiAlignment(self.target.*);
2358 const stack_offset = try self.allocMem(inst, abi_size, abi_align);2364 const stack_offset = try self.allocMem(inst, abi_size, abi_align);
...@@ -3879,7 +3885,7 @@ fn lowerDeclRef(self: *Self, tv: TypedValue, decl: *Module.Decl) InnerError!MCVa...@@ -3879,7 +3885,7 @@ fn lowerDeclRef(self: *Self, tv: TypedValue, decl: *Module.Decl) InnerError!MCVa
3879}3885}
38803886
3881fn lowerUnnamedConst(self: *Self, tv: TypedValue) InnerError!MCValue {3887fn lowerUnnamedConst(self: *Self, tv: TypedValue) InnerError!MCValue {
3882 log.debug("lowerUnnamedConst: ty = {}, val = {}", .{ tv.ty, tv.val.fmtDebug() });3888 log.debug("lowerUnnamedConst: ty = {}, val = {}", .{ tv.ty.fmtDebug(), tv.val.fmtDebug() });
3883 const local_sym_index = self.bin_file.lowerUnnamedConst(tv, self.mod_fn.owner_decl) catch |err| {3889 const local_sym_index = self.bin_file.lowerUnnamedConst(tv, self.mod_fn.owner_decl) catch |err| {
3884 return self.fail("lowering unnamed constant failed: {s}", .{@errorName(err)});3890 return self.fail("lowering unnamed constant failed: {s}", .{@errorName(err)});
3885 };3891 };
...@@ -3907,6 +3913,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {...@@ -3907,6 +3913,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
3907 if (typed_value.val.castTag(.decl_ref_mut)) |payload| {3913 if (typed_value.val.castTag(.decl_ref_mut)) |payload| {
3908 return self.lowerDeclRef(typed_value, payload.data.decl);3914 return self.lowerDeclRef(typed_value, payload.data.decl);
3909 }3915 }
3916 const target = self.target.*;
39103917
3911 switch (typed_value.ty.zigTypeTag()) {3918 switch (typed_value.ty.zigTypeTag()) {
3912 .Pointer => switch (typed_value.ty.ptrSize()) {3919 .Pointer => switch (typed_value.ty.ptrSize()) {
...@@ -3916,7 +3923,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {...@@ -3916,7 +3923,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
3916 else => {3923 else => {
3917 switch (typed_value.val.tag()) {3924 switch (typed_value.val.tag()) {
3918 .int_u64 => {3925 .int_u64 => {
3919 return MCValue{ .immediate = typed_value.val.toUnsignedInt() };3926 return MCValue{ .immediate = typed_value.val.toUnsignedInt(target) };
3920 },3927 },
3921 .slice => {3928 .slice => {
3922 return self.lowerUnnamedConst(typed_value);3929 return self.lowerUnnamedConst(typed_value);
...@@ -3935,7 +3942,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {...@@ -3935,7 +3942,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
3935 const signed = typed_value.val.toSignedInt();3942 const signed = typed_value.val.toSignedInt();
3936 break :blk @bitCast(u64, signed);3943 break :blk @bitCast(u64, signed);
3937 },3944 },
3938 .unsigned => typed_value.val.toUnsignedInt(),3945 .unsigned => typed_value.val.toUnsignedInt(target),
3939 };3946 };
39403947
3941 return MCValue{ .immediate = unsigned };3948 return MCValue{ .immediate = unsigned };
...@@ -4004,20 +4011,20 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {...@@ -4004,20 +4011,20 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
4004 }4011 }
40054012
4006 _ = pl;4013 _ = pl;
4007 return self.fail("TODO implement error union const of type '{}' (non-error)", .{typed_value.ty});4014 return self.fail("TODO implement error union const of type '{}' (non-error)", .{typed_value.ty.fmtDebug()});
4008 } else {4015 } else {
4009 if (!payload_type.hasRuntimeBits()) {4016 if (!payload_type.hasRuntimeBits()) {
4010 // We use the error type directly as the type.4017 // We use the error type directly as the type.
4011 return self.genTypedValue(.{ .ty = error_type, .val = typed_value.val });4018 return self.genTypedValue(.{ .ty = error_type, .val = typed_value.val });
4012 }4019 }
40134020
4014 return self.fail("TODO implement error union const of type '{}' (error)", .{typed_value.ty});4021 return self.fail("TODO implement error union const of type '{}' (error)", .{typed_value.ty.fmtDebug()});
4015 }4022 }
4016 },4023 },
4017 .Struct => {4024 .Struct => {
4018 return self.lowerUnnamedConst(typed_value);4025 return self.lowerUnnamedConst(typed_value);
4019 },4026 },
4020 else => return self.fail("TODO implement const of type '{}'", .{typed_value.ty}),4027 else => return self.fail("TODO implement const of type '{}'", .{typed_value.ty.fmtDebug()}),
4021 }4028 }
4022}4029}
40234030
src/arch/arm/CodeGen.zig+14-10
...@@ -801,8 +801,9 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {...@@ -801,8 +801,9 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
801 return self.next_stack_offset;801 return self.next_stack_offset;
802 }802 }
803803
804 const target = self.target.*;
804 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {805 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {
805 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty});806 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(target)});
806 };807 };
807 // TODO swap this for inst.ty.ptrAlign808 // TODO swap this for inst.ty.ptrAlign
808 const abi_align = elem_ty.abiAlignment(self.target.*);809 const abi_align = elem_ty.abiAlignment(self.target.*);
...@@ -811,8 +812,9 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {...@@ -811,8 +812,9 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
811812
812fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {813fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {
813 const elem_ty = self.air.typeOfIndex(inst);814 const elem_ty = self.air.typeOfIndex(inst);
815 const target = self.target.*;
814 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {816 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {
815 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty});817 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(target)});
816 };818 };
817 const abi_align = elem_ty.abiAlignment(self.target.*);819 const abi_align = elem_ty.abiAlignment(self.target.*);
818 if (abi_align > self.stack_align)820 if (abi_align > self.stack_align)
...@@ -2195,6 +2197,7 @@ fn binOp(...@@ -2195,6 +2197,7 @@ fn binOp(
2195 lhs_ty: Type,2197 lhs_ty: Type,
2196 rhs_ty: Type,2198 rhs_ty: Type,
2197) InnerError!MCValue {2199) InnerError!MCValue {
2200 const target = self.target.*;
2198 switch (tag) {2201 switch (tag) {
2199 .add,2202 .add,
2200 .sub,2203 .sub,
...@@ -2204,7 +2207,7 @@ fn binOp(...@@ -2204,7 +2207,7 @@ fn binOp(
2204 .Float => return self.fail("TODO ARM binary operations on floats", .{}),2207 .Float => return self.fail("TODO ARM binary operations on floats", .{}),
2205 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),2208 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
2206 .Int => {2209 .Int => {
2207 assert(lhs_ty.eql(rhs_ty));2210 assert(lhs_ty.eql(rhs_ty, target));
2208 const int_info = lhs_ty.intInfo(self.target.*);2211 const int_info = lhs_ty.intInfo(self.target.*);
2209 if (int_info.bits <= 32) {2212 if (int_info.bits <= 32) {
2210 // Only say yes if the operation is2213 // Only say yes if the operation is
...@@ -2245,7 +2248,7 @@ fn binOp(...@@ -2245,7 +2248,7 @@ fn binOp(
2245 .Float => return self.fail("TODO ARM binary operations on floats", .{}),2248 .Float => return self.fail("TODO ARM binary operations on floats", .{}),
2246 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),2249 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
2247 .Int => {2250 .Int => {
2248 assert(lhs_ty.eql(rhs_ty));2251 assert(lhs_ty.eql(rhs_ty, target));
2249 const int_info = lhs_ty.intInfo(self.target.*);2252 const int_info = lhs_ty.intInfo(self.target.*);
2250 if (int_info.bits <= 32) {2253 if (int_info.bits <= 32) {
2251 // TODO add optimisations for multiplication2254 // TODO add optimisations for multiplication
...@@ -2299,7 +2302,7 @@ fn binOp(...@@ -2299,7 +2302,7 @@ fn binOp(
2299 switch (lhs_ty.zigTypeTag()) {2302 switch (lhs_ty.zigTypeTag()) {
2300 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),2303 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
2301 .Int => {2304 .Int => {
2302 assert(lhs_ty.eql(rhs_ty));2305 assert(lhs_ty.eql(rhs_ty, target));
2303 const int_info = lhs_ty.intInfo(self.target.*);2306 const int_info = lhs_ty.intInfo(self.target.*);
2304 if (int_info.bits <= 32) {2307 if (int_info.bits <= 32) {
2305 const lhs_immediate_ok = lhs == .immediate and Instruction.Operand.fromU32(lhs.immediate) != null;2308 const lhs_immediate_ok = lhs == .immediate and Instruction.Operand.fromU32(lhs.immediate) != null;
...@@ -4376,6 +4379,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {...@@ -4376,6 +4379,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
4376 if (typed_value.val.castTag(.decl_ref_mut)) |payload| {4379 if (typed_value.val.castTag(.decl_ref_mut)) |payload| {
4377 return self.lowerDeclRef(typed_value, payload.data.decl);4380 return self.lowerDeclRef(typed_value, payload.data.decl);
4378 }4381 }
4382 const target = self.target.*;
43794383
4380 switch (typed_value.ty.zigTypeTag()) {4384 switch (typed_value.ty.zigTypeTag()) {
4381 .Array => {4385 .Array => {
...@@ -4388,7 +4392,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {...@@ -4388,7 +4392,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
4388 else => {4392 else => {
4389 switch (typed_value.val.tag()) {4393 switch (typed_value.val.tag()) {
4390 .int_u64 => {4394 .int_u64 => {
4391 return MCValue{ .immediate = @intCast(u32, typed_value.val.toUnsignedInt()) };4395 return MCValue{ .immediate = @intCast(u32, typed_value.val.toUnsignedInt(target)) };
4392 },4396 },
4393 .slice => {4397 .slice => {
4394 return self.lowerUnnamedConst(typed_value);4398 return self.lowerUnnamedConst(typed_value);
...@@ -4407,7 +4411,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {...@@ -4407,7 +4411,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
4407 const signed = @intCast(i32, typed_value.val.toSignedInt());4411 const signed = @intCast(i32, typed_value.val.toSignedInt());
4408 break :blk @bitCast(u32, signed);4412 break :blk @bitCast(u32, signed);
4409 },4413 },
4410 .unsigned => @intCast(u32, typed_value.val.toUnsignedInt()),4414 .unsigned => @intCast(u32, typed_value.val.toUnsignedInt(target)),
4411 };4415 };
44124416
4413 return MCValue{ .immediate = unsigned };4417 return MCValue{ .immediate = unsigned };
...@@ -4476,20 +4480,20 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {...@@ -4476,20 +4480,20 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
4476 }4480 }
44774481
4478 _ = pl;4482 _ = pl;
4479 return self.fail("TODO implement error union const of type '{}' (non-error)", .{typed_value.ty});4483 return self.fail("TODO implement error union const of type '{}' (non-error)", .{typed_value.ty.fmtDebug()});
4480 } else {4484 } else {
4481 if (!payload_type.hasRuntimeBits()) {4485 if (!payload_type.hasRuntimeBits()) {
4482 // We use the error type directly as the type.4486 // We use the error type directly as the type.
4483 return self.genTypedValue(.{ .ty = error_type, .val = typed_value.val });4487 return self.genTypedValue(.{ .ty = error_type, .val = typed_value.val });
4484 }4488 }
44854489
4486 return self.fail("TODO implement error union const of type '{}' (error)", .{typed_value.ty});4490 return self.fail("TODO implement error union const of type '{}' (error)", .{typed_value.ty.fmtDebug()});
4487 }4491 }
4488 },4492 },
4489 .Struct => {4493 .Struct => {
4490 return self.lowerUnnamedConst(typed_value);4494 return self.lowerUnnamedConst(typed_value);
4491 },4495 },
4492 else => return self.fail("TODO implement const of type '{}'", .{typed_value.ty}),4496 else => return self.fail("TODO implement const of type '{}'", .{typed_value.ty.fmtDebug()}),
4493 }4497 }
4494}4498}
44954499
src/arch/arm/Emit.zig+3-2
...@@ -384,7 +384,7 @@ fn addDbgInfoTypeReloc(self: *Emit, ty: Type) !void {...@@ -384,7 +384,7 @@ fn addDbgInfoTypeReloc(self: *Emit, ty: Type) !void {
384 const index = dbg_out.dbg_info.items.len;384 const index = dbg_out.dbg_info.items.len;
385 try dbg_out.dbg_info.resize(index + 4); // DW.AT.type, DW.FORM.ref4385 try dbg_out.dbg_info.resize(index + 4); // DW.AT.type, DW.FORM.ref4
386386
387 const gop = try dbg_out.dbg_info_type_relocs.getOrPut(self.bin_file.allocator, ty);387 const gop = try dbg_out.dbg_info_type_relocs.getOrPutContext(self.bin_file.allocator, ty, .{ .target = self.target.* });
388 if (!gop.found_existing) {388 if (!gop.found_existing) {
389 gop.value_ptr.* = .{389 gop.value_ptr.* = .{
390 .off = undefined,390 .off = undefined,
...@@ -404,6 +404,7 @@ fn genArgDbgInfo(self: *Emit, inst: Air.Inst.Index, arg_index: u32) !void {...@@ -404,6 +404,7 @@ fn genArgDbgInfo(self: *Emit, inst: Air.Inst.Index, arg_index: u32) !void {
404 const ty = self.function.air.instructions.items(.data)[inst].ty;404 const ty = self.function.air.instructions.items(.data)[inst].ty;
405 const name = self.function.mod_fn.getParamName(arg_index);405 const name = self.function.mod_fn.getParamName(arg_index);
406 const name_with_null = name.ptr[0 .. name.len + 1];406 const name_with_null = name.ptr[0 .. name.len + 1];
407 const target = self.target.*;
407408
408 switch (mcv) {409 switch (mcv) {
409 .register => |reg| {410 .register => |reg| {
...@@ -429,7 +430,7 @@ fn genArgDbgInfo(self: *Emit, inst: Air.Inst.Index, arg_index: u32) !void {...@@ -429,7 +430,7 @@ fn genArgDbgInfo(self: *Emit, inst: Air.Inst.Index, arg_index: u32) !void {
429 switch (self.debug_output) {430 switch (self.debug_output) {
430 .dwarf => |dbg_out| {431 .dwarf => |dbg_out| {
431 const abi_size = math.cast(u32, ty.abiSize(self.target.*)) catch {432 const abi_size = math.cast(u32, ty.abiSize(self.target.*)) catch {
432 return self.fail("type '{}' too big to fit into stack frame", .{ty});433 return self.fail("type '{}' too big to fit into stack frame", .{ty.fmt(target)});
433 };434 };
434 const adjusted_stack_offset = switch (mcv) {435 const adjusted_stack_offset = switch (mcv) {
435 .stack_offset => |offset| math.negateCast(offset + abi_size) catch {436 .stack_offset => |offset| math.negateCast(offset + abi_size) catch {
src/arch/riscv64/CodeGen.zig+15-10
...@@ -749,7 +749,9 @@ fn addDbgInfoTypeReloc(self: *Self, ty: Type) !void {...@@ -749,7 +749,9 @@ fn addDbgInfoTypeReloc(self: *Self, ty: Type) !void {
749 const index = dbg_out.dbg_info.items.len;749 const index = dbg_out.dbg_info.items.len;
750 try dbg_out.dbg_info.resize(index + 4); // DW.AT.type, DW.FORM.ref4750 try dbg_out.dbg_info.resize(index + 4); // DW.AT.type, DW.FORM.ref4
751751
752 const gop = try dbg_out.dbg_info_type_relocs.getOrPut(self.gpa, ty);752 const gop = try dbg_out.dbg_info_type_relocs.getOrPutContext(self.gpa, ty, .{
753 .target = self.target.*,
754 });
753 if (!gop.found_existing) {755 if (!gop.found_existing) {
754 gop.value_ptr.* = .{756 gop.value_ptr.* = .{
755 .off = undefined,757 .off = undefined,
...@@ -781,8 +783,9 @@ fn allocMem(self: *Self, inst: Air.Inst.Index, abi_size: u32, abi_align: u32) !u...@@ -781,8 +783,9 @@ fn allocMem(self: *Self, inst: Air.Inst.Index, abi_size: u32, abi_align: u32) !u
781/// Use a pointer instruction as the basis for allocating stack memory.783/// Use a pointer instruction as the basis for allocating stack memory.
782fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {784fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
783 const elem_ty = self.air.typeOfIndex(inst).elemType();785 const elem_ty = self.air.typeOfIndex(inst).elemType();
786 const target = self.target.*;
784 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {787 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {
785 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty});788 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(target)});
786 };789 };
787 // TODO swap this for inst.ty.ptrAlign790 // TODO swap this for inst.ty.ptrAlign
788 const abi_align = elem_ty.abiAlignment(self.target.*);791 const abi_align = elem_ty.abiAlignment(self.target.*);
...@@ -791,8 +794,9 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {...@@ -791,8 +794,9 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
791794
792fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {795fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {
793 const elem_ty = self.air.typeOfIndex(inst);796 const elem_ty = self.air.typeOfIndex(inst);
797 const target = self.target.*;
794 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {798 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {
795 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty});799 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(target)});
796 };800 };
797 const abi_align = elem_ty.abiAlignment(self.target.*);801 const abi_align = elem_ty.abiAlignment(self.target.*);
798 if (abi_align > self.stack_align)802 if (abi_align > self.stack_align)
...@@ -1048,7 +1052,7 @@ fn binOp(...@@ -1048,7 +1052,7 @@ fn binOp(
1048 .Float => return self.fail("TODO binary operations on floats", .{}),1052 .Float => return self.fail("TODO binary operations on floats", .{}),
1049 .Vector => return self.fail("TODO binary operations on vectors", .{}),1053 .Vector => return self.fail("TODO binary operations on vectors", .{}),
1050 .Int => {1054 .Int => {
1051 assert(lhs_ty.eql(rhs_ty));1055 assert(lhs_ty.eql(rhs_ty, self.target.*));
1052 const int_info = lhs_ty.intInfo(self.target.*);1056 const int_info = lhs_ty.intInfo(self.target.*);
1053 if (int_info.bits <= 64) {1057 if (int_info.bits <= 64) {
1054 // TODO immediate operands1058 // TODO immediate operands
...@@ -1778,7 +1782,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {...@@ -1778,7 +1782,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
1778 if (self.liveness.isUnused(inst))1782 if (self.liveness.isUnused(inst))
1779 return self.finishAir(inst, .dead, .{ bin_op.lhs, bin_op.rhs, .none });1783 return self.finishAir(inst, .dead, .{ bin_op.lhs, bin_op.rhs, .none });
1780 const ty = self.air.typeOf(bin_op.lhs);1784 const ty = self.air.typeOf(bin_op.lhs);
1781 assert(ty.eql(self.air.typeOf(bin_op.rhs)));1785 assert(ty.eql(self.air.typeOf(bin_op.rhs), self.target.*));
1782 if (ty.zigTypeTag() == .ErrorSet)1786 if (ty.zigTypeTag() == .ErrorSet)
1783 return self.fail("TODO implement cmp for errors", .{});1787 return self.fail("TODO implement cmp for errors", .{});
17841788
...@@ -2531,6 +2535,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {...@@ -2531,6 +2535,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
2531 if (typed_value.val.castTag(.decl_ref_mut)) |payload| {2535 if (typed_value.val.castTag(.decl_ref_mut)) |payload| {
2532 return self.lowerDeclRef(typed_value, payload.data.decl);2536 return self.lowerDeclRef(typed_value, payload.data.decl);
2533 }2537 }
2538 const target = self.target.*;
2534 const ptr_bits = self.target.cpu.arch.ptrBitWidth();2539 const ptr_bits = self.target.cpu.arch.ptrBitWidth();
2535 switch (typed_value.ty.zigTypeTag()) {2540 switch (typed_value.ty.zigTypeTag()) {
2536 .Pointer => switch (typed_value.ty.ptrSize()) {2541 .Pointer => switch (typed_value.ty.ptrSize()) {
...@@ -2538,7 +2543,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {...@@ -2538,7 +2543,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
2538 var buf: Type.SlicePtrFieldTypeBuffer = undefined;2543 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
2539 const ptr_type = typed_value.ty.slicePtrFieldType(&buf);2544 const ptr_type = typed_value.ty.slicePtrFieldType(&buf);
2540 const ptr_mcv = try self.genTypedValue(.{ .ty = ptr_type, .val = typed_value.val });2545 const ptr_mcv = try self.genTypedValue(.{ .ty = ptr_type, .val = typed_value.val });
2541 const slice_len = typed_value.val.sliceLen();2546 const slice_len = typed_value.val.sliceLen(target);
2542 // Codegen can't handle some kinds of indirection. If the wrong union field is accessed here it may mean2547 // Codegen can't handle some kinds of indirection. If the wrong union field is accessed here it may mean
2543 // the Sema code needs to use anonymous Decls or alloca instructions to store data.2548 // the Sema code needs to use anonymous Decls or alloca instructions to store data.
2544 const ptr_imm = ptr_mcv.memory;2549 const ptr_imm = ptr_mcv.memory;
...@@ -2549,7 +2554,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {...@@ -2549,7 +2554,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
2549 },2554 },
2550 else => {2555 else => {
2551 if (typed_value.val.tag() == .int_u64) {2556 if (typed_value.val.tag() == .int_u64) {
2552 return MCValue{ .immediate = typed_value.val.toUnsignedInt() };2557 return MCValue{ .immediate = typed_value.val.toUnsignedInt(target) };
2553 }2558 }
2554 return self.fail("TODO codegen more kinds of const pointers", .{});2559 return self.fail("TODO codegen more kinds of const pointers", .{});
2555 },2560 },
...@@ -2559,7 +2564,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {...@@ -2559,7 +2564,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
2559 if (info.bits > ptr_bits or info.signedness == .signed) {2564 if (info.bits > ptr_bits or info.signedness == .signed) {
2560 return self.fail("TODO const int bigger than ptr and signed int", .{});2565 return self.fail("TODO const int bigger than ptr and signed int", .{});
2561 }2566 }
2562 return MCValue{ .immediate = typed_value.val.toUnsignedInt() };2567 return MCValue{ .immediate = typed_value.val.toUnsignedInt(target) };
2563 },2568 },
2564 .Bool => {2569 .Bool => {
2565 return MCValue{ .immediate = @boolToInt(typed_value.val.toBool()) };2570 return MCValue{ .immediate = @boolToInt(typed_value.val.toBool()) };
...@@ -2629,9 +2634,9 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {...@@ -2629,9 +2634,9 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
2629 return self.genTypedValue(.{ .ty = error_type, .val = sub_val });2634 return self.genTypedValue(.{ .ty = error_type, .val = sub_val });
2630 }2635 }
26312636
2632 return self.fail("TODO implement error union const of type '{}'", .{typed_value.ty});2637 return self.fail("TODO implement error union const of type '{}'", .{typed_value.ty.fmtDebug()});
2633 },2638 },
2634 else => return self.fail("TODO implement const of type '{}'", .{typed_value.ty}),2639 else => return self.fail("TODO implement const of type '{}'", .{typed_value.ty.fmtDebug()}),
2635 }2640 }
2636}2641}
26372642
src/arch/wasm/CodeGen.zig+21-14
...@@ -1021,7 +1021,9 @@ fn allocStack(self: *Self, ty: Type) !WValue {...@@ -1021,7 +1021,9 @@ fn allocStack(self: *Self, ty: Type) !WValue {
1021 }1021 }
10221022
1023 const abi_size = std.math.cast(u32, ty.abiSize(self.target)) catch {1023 const abi_size = std.math.cast(u32, ty.abiSize(self.target)) catch {
1024 return self.fail("Type {} with ABI size of {d} exceeds stack frame size", .{ ty, ty.abiSize(self.target) });1024 return self.fail("Type {} with ABI size of {d} exceeds stack frame size", .{
1025 ty.fmt(self.target), ty.abiSize(self.target),
1026 });
1025 };1027 };
1026 const abi_align = ty.abiAlignment(self.target);1028 const abi_align = ty.abiAlignment(self.target);
10271029
...@@ -1053,7 +1055,9 @@ fn allocStackPtr(self: *Self, inst: Air.Inst.Index) !WValue {...@@ -1053,7 +1055,9 @@ fn allocStackPtr(self: *Self, inst: Air.Inst.Index) !WValue {
10531055
1054 const abi_alignment = ptr_ty.ptrAlignment(self.target);1056 const abi_alignment = ptr_ty.ptrAlignment(self.target);
1055 const abi_size = std.math.cast(u32, pointee_ty.abiSize(self.target)) catch {1057 const abi_size = std.math.cast(u32, pointee_ty.abiSize(self.target)) catch {
1056 return self.fail("Type {} with ABI size of {d} exceeds stack frame size", .{ pointee_ty, pointee_ty.abiSize(self.target) });1058 return self.fail("Type {} with ABI size of {d} exceeds stack frame size", .{
1059 pointee_ty.fmt(self.target), pointee_ty.abiSize(self.target),
1060 });
1057 };1061 };
1058 if (abi_alignment > self.stack_alignment) {1062 if (abi_alignment > self.stack_alignment) {
1059 self.stack_alignment = abi_alignment;1063 self.stack_alignment = abi_alignment;
...@@ -1750,7 +1754,7 @@ fn airBinOp(self: *Self, inst: Air.Inst.Index, op: Op) InnerError!WValue {...@@ -1750,7 +1754,7 @@ fn airBinOp(self: *Self, inst: Air.Inst.Index, op: Op) InnerError!WValue {
1750 const operand_ty = self.air.typeOfIndex(inst);1754 const operand_ty = self.air.typeOfIndex(inst);
17511755
1752 if (isByRef(operand_ty, self.target)) {1756 if (isByRef(operand_ty, self.target)) {
1753 return self.fail("TODO: Implement binary operation for type: {}", .{operand_ty});1757 return self.fail("TODO: Implement binary operation for type: {}", .{operand_ty.fmtDebug()});
1754 }1758 }
17551759
1756 try self.emitWValue(lhs);1760 try self.emitWValue(lhs);
...@@ -1918,6 +1922,8 @@ fn lowerConstant(self: *Self, val: Value, ty: Type) InnerError!WValue {...@@ -1918,6 +1922,8 @@ fn lowerConstant(self: *Self, val: Value, ty: Type) InnerError!WValue {
1918 return self.lowerDeclRefValue(.{ .ty = ty, .val = val }, decl);1922 return self.lowerDeclRefValue(.{ .ty = ty, .val = val }, decl);
1919 }1923 }
19201924
1925 const target = self.target;
1926
1921 switch (ty.zigTypeTag()) {1927 switch (ty.zigTypeTag()) {
1922 .Int => {1928 .Int => {
1923 const int_info = ty.intInfo(self.target);1929 const int_info = ty.intInfo(self.target);
...@@ -1929,13 +1935,13 @@ fn lowerConstant(self: *Self, val: Value, ty: Type) InnerError!WValue {...@@ -1929,13 +1935,13 @@ fn lowerConstant(self: *Self, val: Value, ty: Type) InnerError!WValue {
1929 else => unreachable,1935 else => unreachable,
1930 },1936 },
1931 .unsigned => switch (int_info.bits) {1937 .unsigned => switch (int_info.bits) {
1932 0...32 => return WValue{ .imm32 = @intCast(u32, val.toUnsignedInt()) },1938 0...32 => return WValue{ .imm32 = @intCast(u32, val.toUnsignedInt(target)) },
1933 33...64 => return WValue{ .imm64 = val.toUnsignedInt() },1939 33...64 => return WValue{ .imm64 = val.toUnsignedInt(target) },
1934 else => unreachable,1940 else => unreachable,
1935 },1941 },
1936 }1942 }
1937 },1943 },
1938 .Bool => return WValue{ .imm32 = @intCast(u32, val.toUnsignedInt()) },1944 .Bool => return WValue{ .imm32 = @intCast(u32, val.toUnsignedInt(target)) },
1939 .Float => switch (ty.floatBits(self.target)) {1945 .Float => switch (ty.floatBits(self.target)) {
1940 0...32 => return WValue{ .float32 = val.toFloat(f32) },1946 0...32 => return WValue{ .float32 = val.toFloat(f32) },
1941 33...64 => return WValue{ .float64 = val.toFloat(f64) },1947 33...64 => return WValue{ .float64 = val.toFloat(f64) },
...@@ -1945,7 +1951,7 @@ fn lowerConstant(self: *Self, val: Value, ty: Type) InnerError!WValue {...@@ -1945,7 +1951,7 @@ fn lowerConstant(self: *Self, val: Value, ty: Type) InnerError!WValue {
1945 .field_ptr, .elem_ptr => {1951 .field_ptr, .elem_ptr => {
1946 return self.lowerParentPtr(val, ty.childType());1952 return self.lowerParentPtr(val, ty.childType());
1947 },1953 },
1948 .int_u64, .one => return WValue{ .imm32 = @intCast(u32, val.toUnsignedInt()) },1954 .int_u64, .one => return WValue{ .imm32 = @intCast(u32, val.toUnsignedInt(target)) },
1949 .zero, .null_value => return WValue{ .imm32 = 0 },1955 .zero, .null_value => return WValue{ .imm32 = 0 },
1950 else => return self.fail("Wasm TODO: lowerConstant for other const pointer tag {s}", .{val.tag()}),1956 else => return self.fail("Wasm TODO: lowerConstant for other const pointer tag {s}", .{val.tag()}),
1951 },1957 },
...@@ -2044,6 +2050,7 @@ fn emitUndefined(self: *Self, ty: Type) InnerError!WValue {...@@ -2044,6 +2050,7 @@ fn emitUndefined(self: *Self, ty: Type) InnerError!WValue {
2044/// It's illegal to provide a value with a type that cannot be represented2050/// It's illegal to provide a value with a type that cannot be represented
2045/// as an integer value.2051/// as an integer value.
2046fn valueAsI32(self: Self, val: Value, ty: Type) i32 {2052fn valueAsI32(self: Self, val: Value, ty: Type) i32 {
2053 const target = self.target;
2047 switch (ty.zigTypeTag()) {2054 switch (ty.zigTypeTag()) {
2048 .Enum => {2055 .Enum => {
2049 if (val.castTag(.enum_field_index)) |field_index| {2056 if (val.castTag(.enum_field_index)) |field_index| {
...@@ -2071,7 +2078,7 @@ fn valueAsI32(self: Self, val: Value, ty: Type) i32 {...@@ -2071,7 +2078,7 @@ fn valueAsI32(self: Self, val: Value, ty: Type) i32 {
2071 },2078 },
2072 .Int => switch (ty.intInfo(self.target).signedness) {2079 .Int => switch (ty.intInfo(self.target).signedness) {
2073 .signed => return @truncate(i32, val.toSignedInt()),2080 .signed => return @truncate(i32, val.toSignedInt()),
2074 .unsigned => return @bitCast(i32, @truncate(u32, val.toUnsignedInt())),2081 .unsigned => return @bitCast(i32, @truncate(u32, val.toUnsignedInt(target))),
2075 },2082 },
2076 .ErrorSet => {2083 .ErrorSet => {
2077 const kv = self.bin_file.base.options.module.?.getErrorValue(val.getError().?) catch unreachable; // passed invalid `Value` to function2084 const kv = self.bin_file.base.options.module.?.getErrorValue(val.getError().?) catch unreachable; // passed invalid `Value` to function
...@@ -2296,7 +2303,7 @@ fn airStructFieldPtr(self: *Self, inst: Air.Inst.Index) InnerError!WValue {...@@ -2296,7 +2303,7 @@ fn airStructFieldPtr(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
2296 const struct_ty = self.air.typeOf(extra.data.struct_operand).childType();2303 const struct_ty = self.air.typeOf(extra.data.struct_operand).childType();
2297 const offset = std.math.cast(u32, struct_ty.structFieldOffset(extra.data.field_index, self.target)) catch {2304 const offset = std.math.cast(u32, struct_ty.structFieldOffset(extra.data.field_index, self.target)) catch {
2298 return self.fail("Field type '{}' too big to fit into stack frame", .{2305 return self.fail("Field type '{}' too big to fit into stack frame", .{
2299 struct_ty.structFieldType(extra.data.field_index),2306 struct_ty.structFieldType(extra.data.field_index).fmt(self.target),
2300 });2307 });
2301 };2308 };
2302 return self.structFieldPtr(struct_ptr, offset);2309 return self.structFieldPtr(struct_ptr, offset);
...@@ -2309,7 +2316,7 @@ fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u32) InnerEr...@@ -2309,7 +2316,7 @@ fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u32) InnerEr
2309 const field_ty = struct_ty.structFieldType(index);2316 const field_ty = struct_ty.structFieldType(index);
2310 const offset = std.math.cast(u32, struct_ty.structFieldOffset(index, self.target)) catch {2317 const offset = std.math.cast(u32, struct_ty.structFieldOffset(index, self.target)) catch {
2311 return self.fail("Field type '{}' too big to fit into stack frame", .{2318 return self.fail("Field type '{}' too big to fit into stack frame", .{
2312 field_ty,2319 field_ty.fmt(self.target),
2313 });2320 });
2314 };2321 };
2315 return self.structFieldPtr(struct_ptr, offset);2322 return self.structFieldPtr(struct_ptr, offset);
...@@ -2335,7 +2342,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) InnerError!WValue {...@@ -2335,7 +2342,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
2335 const field_ty = struct_ty.structFieldType(field_index);2342 const field_ty = struct_ty.structFieldType(field_index);
2336 if (!field_ty.hasRuntimeBits()) return WValue{ .none = {} };2343 if (!field_ty.hasRuntimeBits()) return WValue{ .none = {} };
2337 const offset = std.math.cast(u32, struct_ty.structFieldOffset(field_index, self.target)) catch {2344 const offset = std.math.cast(u32, struct_ty.structFieldOffset(field_index, self.target)) catch {
2338 return self.fail("Field type '{}' too big to fit into stack frame", .{field_ty});2345 return self.fail("Field type '{}' too big to fit into stack frame", .{field_ty.fmt(self.target)});
2339 };2346 };
23402347
2341 if (isByRef(field_ty, self.target)) {2348 if (isByRef(field_ty, self.target)) {
...@@ -2716,7 +2723,7 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) InnerError!WValue...@@ -2716,7 +2723,7 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) InnerError!WValue
2716 var buf: Type.Payload.ElemType = undefined;2723 var buf: Type.Payload.ElemType = undefined;
2717 const payload_ty = opt_ty.optionalChild(&buf);2724 const payload_ty = opt_ty.optionalChild(&buf);
2718 if (!payload_ty.hasRuntimeBits()) {2725 if (!payload_ty.hasRuntimeBits()) {
2719 return self.fail("TODO: Implement OptionalPayloadPtrSet for optional with zero-sized type {}", .{payload_ty});2726 return self.fail("TODO: Implement OptionalPayloadPtrSet for optional with zero-sized type {}", .{payload_ty.fmtDebug()});
2720 }2727 }
27212728
2722 if (opt_ty.isPtrLikeOptional()) {2729 if (opt_ty.isPtrLikeOptional()) {
...@@ -2724,7 +2731,7 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) InnerError!WValue...@@ -2724,7 +2731,7 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) InnerError!WValue
2724 }2731 }
27252732
2726 const offset = std.math.cast(u32, opt_ty.abiSize(self.target) - payload_ty.abiSize(self.target)) catch {2733 const offset = std.math.cast(u32, opt_ty.abiSize(self.target) - payload_ty.abiSize(self.target)) catch {
2727 return self.fail("Optional type {} too big to fit into stack frame", .{opt_ty});2734 return self.fail("Optional type {} too big to fit into stack frame", .{opt_ty.fmt(self.target)});
2728 };2735 };
27292736
2730 try self.emitWValue(operand);2737 try self.emitWValue(operand);
...@@ -2753,7 +2760,7 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) InnerError!WValue {...@@ -2753,7 +2760,7 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
2753 return operand;2760 return operand;
2754 }2761 }
2755 const offset = std.math.cast(u32, op_ty.abiSize(self.target) - payload_ty.abiSize(self.target)) catch {2762 const offset = std.math.cast(u32, op_ty.abiSize(self.target) - payload_ty.abiSize(self.target)) catch {
2756 return self.fail("Optional type {} too big to fit into stack frame", .{op_ty});2763 return self.fail("Optional type {} too big to fit into stack frame", .{op_ty.fmt(self.target)});
2757 };2764 };
27582765
2759 // Create optional type, set the non-null bit, and store the operand inside the optional type2766 // Create optional type, set the non-null bit, and store the operand inside the optional type
src/arch/x86_64/CodeGen.zig+12-8
...@@ -892,8 +892,9 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {...@@ -892,8 +892,9 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
892 return self.allocMem(inst, @sizeOf(usize), @alignOf(usize));892 return self.allocMem(inst, @sizeOf(usize), @alignOf(usize));
893 }893 }
894894
895 const target = self.target.*;
895 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {896 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {
896 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty});897 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(target)});
897 };898 };
898 // TODO swap this for inst.ty.ptrAlign899 // TODO swap this for inst.ty.ptrAlign
899 const abi_align = ptr_ty.ptrAlignment(self.target.*);900 const abi_align = ptr_ty.ptrAlignment(self.target.*);
...@@ -902,8 +903,9 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {...@@ -902,8 +903,9 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
902903
903fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {904fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {
904 const elem_ty = self.air.typeOfIndex(inst);905 const elem_ty = self.air.typeOfIndex(inst);
906 const target = self.target.*;
905 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {907 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {
906 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty});908 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(target)});
907 };909 };
908 const abi_align = elem_ty.abiAlignment(self.target.*);910 const abi_align = elem_ty.abiAlignment(self.target.*);
909 if (abi_align > self.stack_align)911 if (abi_align > self.stack_align)
...@@ -1142,7 +1144,7 @@ fn airMin(self: *Self, inst: Air.Inst.Index) !void {...@@ -1142,7 +1144,7 @@ fn airMin(self: *Self, inst: Air.Inst.Index) !void {
11421144
1143 const ty = self.air.typeOfIndex(inst);1145 const ty = self.air.typeOfIndex(inst);
1144 if (ty.zigTypeTag() != .Int) {1146 if (ty.zigTypeTag() != .Int) {
1145 return self.fail("TODO implement min for type {}", .{ty});1147 return self.fail("TODO implement min for type {}", .{ty.fmtDebug()});
1146 }1148 }
1147 const signedness = ty.intInfo(self.target.*).signedness;1149 const signedness = ty.intInfo(self.target.*).signedness;
1148 const result: MCValue = result: {1150 const result: MCValue = result: {
...@@ -1676,13 +1678,13 @@ fn airShl(self: *Self, inst: Air.Inst.Index) !void {...@@ -1676,13 +1678,13 @@ fn airShl(self: *Self, inst: Air.Inst.Index) !void {
1676 const ty = self.air.typeOfIndex(inst);1678 const ty = self.air.typeOfIndex(inst);
1677 const tag = self.air.instructions.items(.tag)[inst];1679 const tag = self.air.instructions.items(.tag)[inst];
1678 switch (tag) {1680 switch (tag) {
1679 .shl_exact => return self.fail("TODO implement {} for type {}", .{ tag, ty }),1681 .shl_exact => return self.fail("TODO implement {} for type {}", .{ tag, ty.fmtDebug() }),
1680 .shl => {},1682 .shl => {},
1681 else => unreachable,1683 else => unreachable,
1682 }1684 }
16831685
1684 if (ty.zigTypeTag() != .Int) {1686 if (ty.zigTypeTag() != .Int) {
1685 return self.fail("TODO implement .shl for type {}", .{ty});1687 return self.fail("TODO implement .shl for type {}", .{ty.fmtDebug()});
1686 }1688 }
1687 if (ty.abiSize(self.target.*) > 8) {1689 if (ty.abiSize(self.target.*) > 8) {
1688 return self.fail("TODO implement .shl for integers larger than 8 bytes", .{});1690 return self.fail("TODO implement .shl for integers larger than 8 bytes", .{});
...@@ -5820,7 +5822,7 @@ fn lowerDeclRef(self: *Self, tv: TypedValue, decl: *Module.Decl) InnerError!MCVa...@@ -5820,7 +5822,7 @@ fn lowerDeclRef(self: *Self, tv: TypedValue, decl: *Module.Decl) InnerError!MCVa
5820}5822}
58215823
5822fn lowerUnnamedConst(self: *Self, tv: TypedValue) InnerError!MCValue {5824fn lowerUnnamedConst(self: *Self, tv: TypedValue) InnerError!MCValue {
5823 log.debug("lowerUnnamedConst: ty = {}, val = {}", .{ tv.ty, tv.val.fmtDebug() });5825 log.debug("lowerUnnamedConst: ty = {}, val = {}", .{ tv.ty.fmtDebug(), tv.val.fmtDebug() });
5824 const local_sym_index = self.bin_file.lowerUnnamedConst(tv, self.mod_fn.owner_decl) catch |err| {5826 const local_sym_index = self.bin_file.lowerUnnamedConst(tv, self.mod_fn.owner_decl) catch |err| {
5825 return self.fail("lowering unnamed constant failed: {s}", .{@errorName(err)});5827 return self.fail("lowering unnamed constant failed: {s}", .{@errorName(err)});
5826 };5828 };
...@@ -5850,13 +5852,15 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {...@@ -5850,13 +5852,15 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
5850 return self.lowerDeclRef(typed_value, payload.data.decl);5852 return self.lowerDeclRef(typed_value, payload.data.decl);
5851 }5853 }
58525854
5855 const target = self.target.*;
5856
5853 switch (typed_value.ty.zigTypeTag()) {5857 switch (typed_value.ty.zigTypeTag()) {
5854 .Pointer => switch (typed_value.ty.ptrSize()) {5858 .Pointer => switch (typed_value.ty.ptrSize()) {
5855 .Slice => {},5859 .Slice => {},
5856 else => {5860 else => {
5857 switch (typed_value.val.tag()) {5861 switch (typed_value.val.tag()) {
5858 .int_u64 => {5862 .int_u64 => {
5859 return MCValue{ .immediate = typed_value.val.toUnsignedInt() };5863 return MCValue{ .immediate = typed_value.val.toUnsignedInt(target) };
5860 },5864 },
5861 else => {},5865 else => {},
5862 }5866 }
...@@ -5868,7 +5872,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {...@@ -5868,7 +5872,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
5868 return MCValue{ .immediate = @bitCast(u64, typed_value.val.toSignedInt()) };5872 return MCValue{ .immediate = @bitCast(u64, typed_value.val.toSignedInt()) };
5869 }5873 }
5870 if (!(info.bits > ptr_bits or info.signedness == .signed)) {5874 if (!(info.bits > ptr_bits or info.signedness == .signed)) {
5871 return MCValue{ .immediate = typed_value.val.toUnsignedInt() };5875 return MCValue{ .immediate = typed_value.val.toUnsignedInt(target) };
5872 }5876 }
5873 },5877 },
5874 .Bool => {5878 .Bool => {
src/arch/x86_64/Emit.zig+3-1
...@@ -1118,7 +1118,9 @@ fn addDbgInfoTypeReloc(emit: *Emit, ty: Type) !void {...@@ -1118,7 +1118,9 @@ fn addDbgInfoTypeReloc(emit: *Emit, ty: Type) !void {
1118 const index = dbg_out.dbg_info.items.len;1118 const index = dbg_out.dbg_info.items.len;
1119 try dbg_out.dbg_info.resize(index + 4); // DW.AT.type, DW.FORM.ref41119 try dbg_out.dbg_info.resize(index + 4); // DW.AT.type, DW.FORM.ref4
11201120
1121 const gop = try dbg_out.dbg_info_type_relocs.getOrPut(emit.bin_file.allocator, ty);1121 const gop = try dbg_out.dbg_info_type_relocs.getOrPutContext(emit.bin_file.allocator, ty, .{
1122 .target = emit.target.*,
1123 });
1122 if (!gop.found_existing) {1124 if (!gop.found_existing) {
1123 gop.value_ptr.* = .{1125 gop.value_ptr.* = .{
1124 .off = undefined,1126 .off = undefined,
src/codegen.zig+19-16
...@@ -165,7 +165,10 @@ pub fn generateSymbol(...@@ -165,7 +165,10 @@ pub fn generateSymbol(
165 const target = bin_file.options.target;165 const target = bin_file.options.target;
166 const endian = target.cpu.arch.endian();166 const endian = target.cpu.arch.endian();
167167
168 log.debug("generateSymbol: ty = {}, val = {}", .{ typed_value.ty, typed_value.val.fmtDebug() });168 log.debug("generateSymbol: ty = {}, val = {}", .{
169 typed_value.ty.fmtDebug(),
170 typed_value.val.fmtDebug(),
171 });
169172
170 if (typed_value.val.isUndefDeep()) {173 if (typed_value.val.isUndefDeep()) {
171 const abi_size = try math.cast(usize, typed_value.ty.abiSize(target));174 const abi_size = try math.cast(usize, typed_value.ty.abiSize(target));
...@@ -295,11 +298,11 @@ pub fn generateSymbol(...@@ -295,11 +298,11 @@ pub fn generateSymbol(
295 .zero, .one, .int_u64, .int_big_positive => {298 .zero, .one, .int_u64, .int_big_positive => {
296 switch (target.cpu.arch.ptrBitWidth()) {299 switch (target.cpu.arch.ptrBitWidth()) {
297 32 => {300 32 => {
298 const x = typed_value.val.toUnsignedInt();301 const x = typed_value.val.toUnsignedInt(target);
299 mem.writeInt(u32, try code.addManyAsArray(4), @intCast(u32, x), endian);302 mem.writeInt(u32, try code.addManyAsArray(4), @intCast(u32, x), endian);
300 },303 },
301 64 => {304 64 => {
302 const x = typed_value.val.toUnsignedInt();305 const x = typed_value.val.toUnsignedInt(target);
303 mem.writeInt(u64, try code.addManyAsArray(8), x, endian);306 mem.writeInt(u64, try code.addManyAsArray(8), x, endian);
304 },307 },
305 else => unreachable,308 else => unreachable,
...@@ -433,7 +436,7 @@ pub fn generateSymbol(...@@ -433,7 +436,7 @@ pub fn generateSymbol(
433 // TODO populate .debug_info for the integer436 // TODO populate .debug_info for the integer
434 const info = typed_value.ty.intInfo(bin_file.options.target);437 const info = typed_value.ty.intInfo(bin_file.options.target);
435 if (info.bits <= 8) {438 if (info.bits <= 8) {
436 const x = @intCast(u8, typed_value.val.toUnsignedInt());439 const x = @intCast(u8, typed_value.val.toUnsignedInt(target));
437 try code.append(x);440 try code.append(x);
438 return Result{ .appended = {} };441 return Result{ .appended = {} };
439 }442 }
...@@ -443,20 +446,20 @@ pub fn generateSymbol(...@@ -443,20 +446,20 @@ pub fn generateSymbol(
443 bin_file.allocator,446 bin_file.allocator,
444 src_loc,447 src_loc,
445 "TODO implement generateSymbol for big ints ('{}')",448 "TODO implement generateSymbol for big ints ('{}')",
446 .{typed_value.ty},449 .{typed_value.ty.fmtDebug()},
447 ),450 ),
448 };451 };
449 }452 }
450 switch (info.signedness) {453 switch (info.signedness) {
451 .unsigned => {454 .unsigned => {
452 if (info.bits <= 16) {455 if (info.bits <= 16) {
453 const x = @intCast(u16, typed_value.val.toUnsignedInt());456 const x = @intCast(u16, typed_value.val.toUnsignedInt(target));
454 mem.writeInt(u16, try code.addManyAsArray(2), x, endian);457 mem.writeInt(u16, try code.addManyAsArray(2), x, endian);
455 } else if (info.bits <= 32) {458 } else if (info.bits <= 32) {
456 const x = @intCast(u32, typed_value.val.toUnsignedInt());459 const x = @intCast(u32, typed_value.val.toUnsignedInt(target));
457 mem.writeInt(u32, try code.addManyAsArray(4), x, endian);460 mem.writeInt(u32, try code.addManyAsArray(4), x, endian);
458 } else {461 } else {
459 const x = typed_value.val.toUnsignedInt();462 const x = typed_value.val.toUnsignedInt(target);
460 mem.writeInt(u64, try code.addManyAsArray(8), x, endian);463 mem.writeInt(u64, try code.addManyAsArray(8), x, endian);
461 }464 }
462 },465 },
...@@ -482,7 +485,7 @@ pub fn generateSymbol(...@@ -482,7 +485,7 @@ pub fn generateSymbol(
482485
483 const info = typed_value.ty.intInfo(target);486 const info = typed_value.ty.intInfo(target);
484 if (info.bits <= 8) {487 if (info.bits <= 8) {
485 const x = @intCast(u8, int_val.toUnsignedInt());488 const x = @intCast(u8, int_val.toUnsignedInt(target));
486 try code.append(x);489 try code.append(x);
487 return Result{ .appended = {} };490 return Result{ .appended = {} };
488 }491 }
...@@ -492,20 +495,20 @@ pub fn generateSymbol(...@@ -492,20 +495,20 @@ pub fn generateSymbol(
492 bin_file.allocator,495 bin_file.allocator,
493 src_loc,496 src_loc,
494 "TODO implement generateSymbol for big int enums ('{}')",497 "TODO implement generateSymbol for big int enums ('{}')",
495 .{typed_value.ty},498 .{typed_value.ty.fmtDebug()},
496 ),499 ),
497 };500 };
498 }501 }
499 switch (info.signedness) {502 switch (info.signedness) {
500 .unsigned => {503 .unsigned => {
501 if (info.bits <= 16) {504 if (info.bits <= 16) {
502 const x = @intCast(u16, int_val.toUnsignedInt());505 const x = @intCast(u16, int_val.toUnsignedInt(target));
503 mem.writeInt(u16, try code.addManyAsArray(2), x, endian);506 mem.writeInt(u16, try code.addManyAsArray(2), x, endian);
504 } else if (info.bits <= 32) {507 } else if (info.bits <= 32) {
505 const x = @intCast(u32, int_val.toUnsignedInt());508 const x = @intCast(u32, int_val.toUnsignedInt(target));
506 mem.writeInt(u32, try code.addManyAsArray(4), x, endian);509 mem.writeInt(u32, try code.addManyAsArray(4), x, endian);
507 } else {510 } else {
508 const x = int_val.toUnsignedInt();511 const x = int_val.toUnsignedInt(target);
509 mem.writeInt(u64, try code.addManyAsArray(8), x, endian);512 mem.writeInt(u64, try code.addManyAsArray(8), x, endian);
510 }513 }
511 },514 },
...@@ -597,7 +600,7 @@ pub fn generateSymbol(...@@ -597,7 +600,7 @@ pub fn generateSymbol(
597 }600 }
598601
599 const union_ty = typed_value.ty.cast(Type.Payload.Union).?.data;602 const union_ty = typed_value.ty.cast(Type.Payload.Union).?.data;
600 const field_index = union_ty.tag_ty.enumTagFieldIndex(union_obj.tag).?;603 const field_index = union_ty.tag_ty.enumTagFieldIndex(union_obj.tag, target).?;
601 assert(union_ty.haveFieldTypes());604 assert(union_ty.haveFieldTypes());
602 const field_ty = union_ty.fields.values()[field_index].ty;605 const field_ty = union_ty.fields.values()[field_index].ty;
603 if (!field_ty.hasRuntimeBits()) {606 if (!field_ty.hasRuntimeBits()) {
...@@ -787,6 +790,7 @@ fn lowerDeclRef(...@@ -787,6 +790,7 @@ fn lowerDeclRef(
787 debug_output: DebugInfoOutput,790 debug_output: DebugInfoOutput,
788 reloc_info: RelocInfo,791 reloc_info: RelocInfo,
789) GenerateSymbolError!Result {792) GenerateSymbolError!Result {
793 const target = bin_file.options.target;
790 if (typed_value.ty.isSlice()) {794 if (typed_value.ty.isSlice()) {
791 // generate ptr795 // generate ptr
792 var buf: Type.SlicePtrFieldTypeBuffer = undefined;796 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
...@@ -805,7 +809,7 @@ fn lowerDeclRef(...@@ -805,7 +809,7 @@ fn lowerDeclRef(
805 // generate length809 // generate length
806 var slice_len: Value.Payload.U64 = .{810 var slice_len: Value.Payload.U64 = .{
807 .base = .{ .tag = .int_u64 },811 .base = .{ .tag = .int_u64 },
808 .data = typed_value.val.sliceLen(),812 .data = typed_value.val.sliceLen(target),
809 };813 };
810 switch (try generateSymbol(bin_file, src_loc, .{814 switch (try generateSymbol(bin_file, src_loc, .{
811 .ty = Type.usize,815 .ty = Type.usize,
...@@ -821,7 +825,6 @@ fn lowerDeclRef(...@@ -821,7 +825,6 @@ fn lowerDeclRef(
821 return Result{ .appended = {} };825 return Result{ .appended = {} };
822 }826 }
823827
824 const target = bin_file.options.target;
825 const ptr_width = target.cpu.arch.ptrBitWidth();828 const ptr_width = target.cpu.arch.ptrBitWidth();
826 const is_fn_body = decl.ty.zigTypeTag() == .Fn;829 const is_fn_body = decl.ty.zigTypeTag() == .Fn;
827 if (!is_fn_body and !decl.ty.hasRuntimeBits()) {830 if (!is_fn_body and !decl.ty.hasRuntimeBits()) {
src/codegen/c.zig+36-21
...@@ -56,8 +56,14 @@ pub const TypedefMap = std.ArrayHashMap(...@@ -56,8 +56,14 @@ pub const TypedefMap = std.ArrayHashMap(
56 true,56 true,
57);57);
5858
59const FormatTypeAsCIdentContext = struct {
60 ty: Type,
61 target: std.Target,
62};
63
64/// TODO make this not cut off at 128 bytes
59fn formatTypeAsCIdentifier(65fn formatTypeAsCIdentifier(
60 data: Type,66 data: FormatTypeAsCIdentContext,
61 comptime fmt: []const u8,67 comptime fmt: []const u8,
62 options: std.fmt.FormatOptions,68 options: std.fmt.FormatOptions,
63 writer: anytype,69 writer: anytype,
...@@ -65,13 +71,15 @@ fn formatTypeAsCIdentifier(...@@ -65,13 +71,15 @@ fn formatTypeAsCIdentifier(
65 _ = fmt;71 _ = fmt;
66 _ = options;72 _ = options;
67 var buffer = [1]u8{0} ** 128;73 var buffer = [1]u8{0} ** 128;
68 // We don't care if it gets cut off, it's still more unique than a number74 var buf = std.fmt.bufPrint(&buffer, "{}", .{data.ty.fmt(data.target)}) catch &buffer;
69 var buf = std.fmt.bufPrint(&buffer, "{}", .{data}) catch &buffer;
70 return formatIdent(buf, "", .{}, writer);75 return formatIdent(buf, "", .{}, writer);
71}76}
7277
73pub fn typeToCIdentifier(t: Type) std.fmt.Formatter(formatTypeAsCIdentifier) {78pub fn typeToCIdentifier(ty: Type, target: std.Target) std.fmt.Formatter(formatTypeAsCIdentifier) {
74 return .{ .data = t };79 return .{ .data = .{
80 .ty = ty,
81 .target = target,
82 } };
75}83}
7684
77const reserved_idents = std.ComptimeStringMap(void, .{85const reserved_idents = std.ComptimeStringMap(void, .{
...@@ -369,6 +377,8 @@ pub const DeclGen = struct {...@@ -369,6 +377,8 @@ pub const DeclGen = struct {
369 ) error{ OutOfMemory, AnalysisFail }!void {377 ) error{ OutOfMemory, AnalysisFail }!void {
370 decl.markAlive();378 decl.markAlive();
371379
380 const target = dg.module.getTarget();
381
372 if (ty.isSlice()) {382 if (ty.isSlice()) {
373 try writer.writeByte('(');383 try writer.writeByte('(');
374 try dg.renderTypecast(writer, ty);384 try dg.renderTypecast(writer, ty);
...@@ -376,7 +386,7 @@ pub const DeclGen = struct {...@@ -376,7 +386,7 @@ pub const DeclGen = struct {
376 var buf: Type.SlicePtrFieldTypeBuffer = undefined;386 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
377 try dg.renderValue(writer, ty.slicePtrFieldType(&buf), val.slicePtr());387 try dg.renderValue(writer, ty.slicePtrFieldType(&buf), val.slicePtr());
378 try writer.writeAll(", ");388 try writer.writeAll(", ");
379 try writer.print("{d}", .{val.sliceLen()});389 try writer.print("{d}", .{val.sliceLen(target)});
380 try writer.writeAll("}");390 try writer.writeAll("}");
381 return;391 return;
382 }392 }
...@@ -388,7 +398,7 @@ pub const DeclGen = struct {...@@ -388,7 +398,7 @@ pub const DeclGen = struct {
388 // somewhere and we should let the C compiler tell us about it.398 // somewhere and we should let the C compiler tell us about it.
389 if (ty.castPtrToFn() == null) {399 if (ty.castPtrToFn() == null) {
390 // Determine if we must pointer cast.400 // Determine if we must pointer cast.
391 if (ty.eql(decl.ty)) {401 if (ty.eql(decl.ty, target)) {
392 try writer.writeByte('&');402 try writer.writeByte('&');
393 try dg.renderDeclName(writer, decl);403 try dg.renderDeclName(writer, decl);
394 return;404 return;
...@@ -508,6 +518,7 @@ pub const DeclGen = struct {...@@ -508,6 +518,7 @@ pub const DeclGen = struct {
508 ty: Type,518 ty: Type,
509 val: Value,519 val: Value,
510 ) error{ OutOfMemory, AnalysisFail }!void {520 ) error{ OutOfMemory, AnalysisFail }!void {
521 const target = dg.module.getTarget();
511 if (val.isUndefDeep()) {522 if (val.isUndefDeep()) {
512 switch (ty.zigTypeTag()) {523 switch (ty.zigTypeTag()) {
513 // Using '{}' for integer and floats seemed to error C compilers (both GCC and Clang)524 // Using '{}' for integer and floats seemed to error C compilers (both GCC and Clang)
...@@ -551,7 +562,7 @@ pub const DeclGen = struct {...@@ -551,7 +562,7 @@ pub const DeclGen = struct {
551 else => {562 else => {
552 if (ty.isSignedInt())563 if (ty.isSignedInt())
553 return writer.print("{d}", .{val.toSignedInt()});564 return writer.print("{d}", .{val.toSignedInt()});
554 return writer.print("{d}u", .{val.toUnsignedInt()});565 return writer.print("{d}u", .{val.toUnsignedInt(target)});
555 },566 },
556 },567 },
557 .Float => {568 .Float => {
...@@ -609,7 +620,7 @@ pub const DeclGen = struct {...@@ -609,7 +620,7 @@ pub const DeclGen = struct {
609 .int_u64, .one => {620 .int_u64, .one => {
610 try writer.writeAll("((");621 try writer.writeAll("((");
611 try dg.renderTypecast(writer, ty);622 try dg.renderTypecast(writer, ty);
612 try writer.print(")0x{x}u)", .{val.toUnsignedInt()});623 try writer.print(")0x{x}u)", .{val.toUnsignedInt(target)});
613 },624 },
614 else => unreachable,625 else => unreachable,
615 },626 },
...@@ -653,7 +664,6 @@ pub const DeclGen = struct {...@@ -653,7 +664,6 @@ pub const DeclGen = struct {
653 if (ty.isPtrLikeOptional()) {664 if (ty.isPtrLikeOptional()) {
654 return dg.renderValue(writer, payload_type, val);665 return dg.renderValue(writer, payload_type, val);
655 }666 }
656 const target = dg.module.getTarget();
657 if (payload_type.abiSize(target) == 0) {667 if (payload_type.abiSize(target) == 0) {
658 const is_null = val.castTag(.opt_payload) == null;668 const is_null = val.castTag(.opt_payload) == null;
659 return writer.print("{}", .{is_null});669 return writer.print("{}", .{is_null});
...@@ -773,7 +783,6 @@ pub const DeclGen = struct {...@@ -773,7 +783,6 @@ pub const DeclGen = struct {
773 .Union => {783 .Union => {
774 const union_obj = val.castTag(.@"union").?.data;784 const union_obj = val.castTag(.@"union").?.data;
775 const union_ty = ty.cast(Type.Payload.Union).?.data;785 const union_ty = ty.cast(Type.Payload.Union).?.data;
776 const target = dg.module.getTarget();
777 const layout = ty.unionGetLayout(target);786 const layout = ty.unionGetLayout(target);
778787
779 try writer.writeAll("(");788 try writer.writeAll("(");
...@@ -789,7 +798,7 @@ pub const DeclGen = struct {...@@ -789,7 +798,7 @@ pub const DeclGen = struct {
789 try writer.writeAll(".payload = {");798 try writer.writeAll(".payload = {");
790 }799 }
791800
792 const index = union_ty.tag_ty.enumTagFieldIndex(union_obj.tag).?;801 const index = union_ty.tag_ty.enumTagFieldIndex(union_obj.tag, target).?;
793 const field_ty = ty.unionFields().values()[index].ty;802 const field_ty = ty.unionFields().values()[index].ty;
794 const field_name = ty.unionFields().keys()[index];803 const field_name = ty.unionFields().keys()[index];
795 if (field_ty.hasRuntimeBits()) {804 if (field_ty.hasRuntimeBits()) {
...@@ -879,8 +888,8 @@ pub const DeclGen = struct {...@@ -879,8 +888,8 @@ pub const DeclGen = struct {
879 try bw.writeAll(" (*");888 try bw.writeAll(" (*");
880889
881 const name_start = buffer.items.len;890 const name_start = buffer.items.len;
882 // TODO: typeToCIdentifier truncates to 128 bytes, we probably don't want to do this891 const target = dg.module.getTarget();
883 try bw.print("zig_F_{s})(", .{typeToCIdentifier(t)});892 try bw.print("zig_F_{s})(", .{typeToCIdentifier(t, target)});
884 const name_end = buffer.items.len - 2;893 const name_end = buffer.items.len - 2;
885894
886 const param_len = fn_info.param_types.len;895 const param_len = fn_info.param_types.len;
...@@ -934,10 +943,11 @@ pub const DeclGen = struct {...@@ -934,10 +943,11 @@ pub const DeclGen = struct {
934943
935 try bw.writeAll("; size_t len; } ");944 try bw.writeAll("; size_t len; } ");
936 const name_index = buffer.items.len;945 const name_index = buffer.items.len;
946 const target = dg.module.getTarget();
937 if (t.isConstPtr()) {947 if (t.isConstPtr()) {
938 try bw.print("zig_L_{s}", .{typeToCIdentifier(child_type)});948 try bw.print("zig_L_{s}", .{typeToCIdentifier(child_type, target)});
939 } else {949 } else {
940 try bw.print("zig_M_{s}", .{typeToCIdentifier(child_type)});950 try bw.print("zig_M_{s}", .{typeToCIdentifier(child_type, target)});
941 }951 }
942 if (ptr_sentinel) |s| {952 if (ptr_sentinel) |s| {
943 try bw.writeAll("_s_");953 try bw.writeAll("_s_");
...@@ -1023,7 +1033,8 @@ pub const DeclGen = struct {...@@ -1023,7 +1033,8 @@ pub const DeclGen = struct {
1023 try buffer.appendSlice("} ");1033 try buffer.appendSlice("} ");
10241034
1025 const name_start = buffer.items.len;1035 const name_start = buffer.items.len;
1026 try writer.print("zig_T_{};\n", .{typeToCIdentifier(t)});1036 const target = dg.module.getTarget();
1037 try writer.print("zig_T_{};\n", .{typeToCIdentifier(t, target)});
10271038
1028 const rendered = buffer.toOwnedSlice();1039 const rendered = buffer.toOwnedSlice();
1029 errdefer dg.typedefs.allocator.free(rendered);1040 errdefer dg.typedefs.allocator.free(rendered);
...@@ -1107,6 +1118,7 @@ pub const DeclGen = struct {...@@ -1107,6 +1118,7 @@ pub const DeclGen = struct {
1107 try dg.renderTypeAndName(bw, child_type, payload_name, .Mut, 0);1118 try dg.renderTypeAndName(bw, child_type, payload_name, .Mut, 0);
1108 try bw.writeAll("; uint16_t error; } ");1119 try bw.writeAll("; uint16_t error; } ");
1109 const name_index = buffer.items.len;1120 const name_index = buffer.items.len;
1121 const target = dg.module.getTarget();
1110 if (err_set_type.castTag(.error_set_inferred)) |inf_err_set_payload| {1122 if (err_set_type.castTag(.error_set_inferred)) |inf_err_set_payload| {
1111 const func = inf_err_set_payload.data.func;1123 const func = inf_err_set_payload.data.func;
1112 try bw.writeAll("zig_E_");1124 try bw.writeAll("zig_E_");
...@@ -1114,7 +1126,7 @@ pub const DeclGen = struct {...@@ -1114,7 +1126,7 @@ pub const DeclGen = struct {
1114 try bw.writeAll(";\n");1126 try bw.writeAll(";\n");
1115 } else {1127 } else {
1116 try bw.print("zig_E_{s}_{s};\n", .{1128 try bw.print("zig_E_{s}_{s};\n", .{
1117 typeToCIdentifier(err_set_type), typeToCIdentifier(child_type),1129 typeToCIdentifier(err_set_type, target), typeToCIdentifier(child_type, target),
1118 });1130 });
1119 }1131 }
11201132
...@@ -1144,7 +1156,8 @@ pub const DeclGen = struct {...@@ -1144,7 +1156,8 @@ pub const DeclGen = struct {
1144 try dg.renderType(bw, elem_type);1156 try dg.renderType(bw, elem_type);
11451157
1146 const name_start = buffer.items.len + 1;1158 const name_start = buffer.items.len + 1;
1147 try bw.print(" zig_A_{s}_{d}", .{ typeToCIdentifier(elem_type), c_len });1159 const target = dg.module.getTarget();
1160 try bw.print(" zig_A_{s}_{d}", .{ typeToCIdentifier(elem_type, target), c_len });
1148 const name_end = buffer.items.len;1161 const name_end = buffer.items.len;
11491162
1150 try bw.print("[{d}];\n", .{c_len});1163 try bw.print("[{d}];\n", .{c_len});
...@@ -1172,7 +1185,8 @@ pub const DeclGen = struct {...@@ -1172,7 +1185,8 @@ pub const DeclGen = struct {
1172 try dg.renderTypeAndName(bw, child_type, payload_name, .Mut, 0);1185 try dg.renderTypeAndName(bw, child_type, payload_name, .Mut, 0);
1173 try bw.writeAll("; bool is_null; } ");1186 try bw.writeAll("; bool is_null; } ");
1174 const name_index = buffer.items.len;1187 const name_index = buffer.items.len;
1175 try bw.print("zig_Q_{s};\n", .{typeToCIdentifier(child_type)});1188 const target = dg.module.getTarget();
1189 try bw.print("zig_Q_{s};\n", .{typeToCIdentifier(child_type, target)});
11761190
1177 const rendered = buffer.toOwnedSlice();1191 const rendered = buffer.toOwnedSlice();
1178 errdefer dg.typedefs.allocator.free(rendered);1192 errdefer dg.typedefs.allocator.free(rendered);
...@@ -2177,12 +2191,13 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -2177,12 +2191,13 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue {
2177 if (src_val_is_undefined)2191 if (src_val_is_undefined)
2178 return try airStoreUndefined(f, dest_ptr);2192 return try airStoreUndefined(f, dest_ptr);
21792193
2194 const target = f.object.dg.module.getTarget();
2180 const writer = f.object.writer();2195 const writer = f.object.writer();
2181 if (lhs_child_type.zigTypeTag() == .Array) {2196 if (lhs_child_type.zigTypeTag() == .Array) {
2182 // For this memcpy to safely work we need the rhs to have the same2197 // For this memcpy to safely work we need the rhs to have the same
2183 // underlying type as the lhs (i.e. they must both be arrays of the same underlying type).2198 // underlying type as the lhs (i.e. they must both be arrays of the same underlying type).
2184 const rhs_type = f.air.typeOf(bin_op.rhs);2199 const rhs_type = f.air.typeOf(bin_op.rhs);
2185 assert(rhs_type.eql(lhs_child_type));2200 assert(rhs_type.eql(lhs_child_type, target));
21862201
2187 // If the source is a constant, writeCValue will emit a brace initialization2202 // If the source is a constant, writeCValue will emit a brace initialization
2188 // so work around this by initializing into new local.2203 // so work around this by initializing into new local.
src/codegen/llvm.zig+54-52
...@@ -812,7 +812,7 @@ pub const Object = struct {...@@ -812,7 +812,7 @@ pub const Object = struct {
812 const gpa = o.gpa;812 const gpa = o.gpa;
813 // Be careful not to reference this `gop` variable after any recursive calls813 // Be careful not to reference this `gop` variable after any recursive calls
814 // to `lowerDebugType`.814 // to `lowerDebugType`.
815 const gop = try o.di_type_map.getOrPut(gpa, ty);815 const gop = try o.di_type_map.getOrPutContext(gpa, ty, .{ .target = o.target });
816 if (gop.found_existing) {816 if (gop.found_existing) {
817 const annotated = gop.value_ptr.*;817 const annotated = gop.value_ptr.*;
818 const di_type = annotated.toDIType();818 const di_type = annotated.toDIType();
...@@ -825,7 +825,7 @@ pub const Object = struct {...@@ -825,7 +825,7 @@ pub const Object = struct {
825 };825 };
826 return o.lowerDebugTypeImpl(entry, resolve, di_type);826 return o.lowerDebugTypeImpl(entry, resolve, di_type);
827 }827 }
828 errdefer assert(o.di_type_map.orderedRemove(ty));828 errdefer assert(o.di_type_map.orderedRemoveContext(ty, .{ .target = o.target }));
829 // The Type memory is ephemeral; since we want to store a longer-lived829 // The Type memory is ephemeral; since we want to store a longer-lived
830 // reference, we need to copy it here.830 // reference, we need to copy it here.
831 gop.key_ptr.* = try ty.copy(o.type_map_arena.allocator());831 gop.key_ptr.* = try ty.copy(o.type_map_arena.allocator());
...@@ -856,7 +856,7 @@ pub const Object = struct {...@@ -856,7 +856,7 @@ pub const Object = struct {
856 .Int => {856 .Int => {
857 const info = ty.intInfo(target);857 const info = ty.intInfo(target);
858 assert(info.bits != 0);858 assert(info.bits != 0);
859 const name = try ty.nameAlloc(gpa);859 const name = try ty.nameAlloc(gpa, target);
860 defer gpa.free(name);860 defer gpa.free(name);
861 const dwarf_encoding: c_uint = switch (info.signedness) {861 const dwarf_encoding: c_uint = switch (info.signedness) {
862 .signed => DW.ATE.signed,862 .signed => DW.ATE.signed,
...@@ -873,7 +873,7 @@ pub const Object = struct {...@@ -873,7 +873,7 @@ pub const Object = struct {
873 const enum_di_ty = try o.makeEmptyNamespaceDIType(owner_decl);873 const enum_di_ty = try o.makeEmptyNamespaceDIType(owner_decl);
874 // The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType`874 // The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType`
875 // means we can't use `gop` anymore.875 // means we can't use `gop` anymore.
876 try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(enum_di_ty));876 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(enum_di_ty), .{ .target = o.target });
877 return enum_di_ty;877 return enum_di_ty;
878 }878 }
879879
...@@ -903,7 +903,7 @@ pub const Object = struct {...@@ -903,7 +903,7 @@ pub const Object = struct {
903 const di_file = try o.getDIFile(gpa, owner_decl.src_namespace.file_scope);903 const di_file = try o.getDIFile(gpa, owner_decl.src_namespace.file_scope);
904 const di_scope = try o.namespaceToDebugScope(owner_decl.src_namespace);904 const di_scope = try o.namespaceToDebugScope(owner_decl.src_namespace);
905905
906 const name = try ty.nameAlloc(gpa);906 const name = try ty.nameAlloc(gpa, target);
907 defer gpa.free(name);907 defer gpa.free(name);
908 var buffer: Type.Payload.Bits = undefined;908 var buffer: Type.Payload.Bits = undefined;
909 const int_ty = ty.intTagType(&buffer);909 const int_ty = ty.intTagType(&buffer);
...@@ -921,12 +921,12 @@ pub const Object = struct {...@@ -921,12 +921,12 @@ pub const Object = struct {
921 "",921 "",
922 );922 );
923 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.923 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
924 try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(enum_di_ty));924 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(enum_di_ty), .{ .target = o.target });
925 return enum_di_ty;925 return enum_di_ty;
926 },926 },
927 .Float => {927 .Float => {
928 const bits = ty.floatBits(target);928 const bits = ty.floatBits(target);
929 const name = try ty.nameAlloc(gpa);929 const name = try ty.nameAlloc(gpa, target);
930 defer gpa.free(name);930 defer gpa.free(name);
931 const di_type = dib.createBasicType(name, bits, DW.ATE.float);931 const di_type = dib.createBasicType(name, bits, DW.ATE.float);
932 gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_type);932 gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_type);
...@@ -974,7 +974,7 @@ pub const Object = struct {...@@ -974,7 +974,7 @@ pub const Object = struct {
974 const bland_ptr_ty = Type.initPayload(&payload.base);974 const bland_ptr_ty = Type.initPayload(&payload.base);
975 const ptr_di_ty = try o.lowerDebugType(bland_ptr_ty, resolve);975 const ptr_di_ty = try o.lowerDebugType(bland_ptr_ty, resolve);
976 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.976 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
977 try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.init(ptr_di_ty, resolve));977 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.init(ptr_di_ty, resolve), .{ .target = o.target });
978 return ptr_di_ty;978 return ptr_di_ty;
979 }979 }
980980
...@@ -983,7 +983,7 @@ pub const Object = struct {...@@ -983,7 +983,7 @@ pub const Object = struct {
983 const ptr_ty = ty.slicePtrFieldType(&buf);983 const ptr_ty = ty.slicePtrFieldType(&buf);
984 const len_ty = Type.usize;984 const len_ty = Type.usize;
985985
986 const name = try ty.nameAlloc(gpa);986 const name = try ty.nameAlloc(gpa, target);
987 defer gpa.free(name);987 defer gpa.free(name);
988 const di_file: ?*llvm.DIFile = null;988 const di_file: ?*llvm.DIFile = null;
989 const line = 0;989 const line = 0;
...@@ -1054,12 +1054,12 @@ pub const Object = struct {...@@ -1054,12 +1054,12 @@ pub const Object = struct {
1054 );1054 );
1055 dib.replaceTemporary(fwd_decl, full_di_ty);1055 dib.replaceTemporary(fwd_decl, full_di_ty);
1056 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.1056 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
1057 try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty));1057 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty), .{ .target = o.target });
1058 return full_di_ty;1058 return full_di_ty;
1059 }1059 }
10601060
1061 const elem_di_ty = try o.lowerDebugType(ptr_info.pointee_type, .fwd);1061 const elem_di_ty = try o.lowerDebugType(ptr_info.pointee_type, .fwd);
1062 const name = try ty.nameAlloc(gpa);1062 const name = try ty.nameAlloc(gpa, target);
1063 defer gpa.free(name);1063 defer gpa.free(name);
1064 const ptr_di_ty = dib.createPointerType(1064 const ptr_di_ty = dib.createPointerType(
1065 elem_di_ty,1065 elem_di_ty,
...@@ -1068,7 +1068,7 @@ pub const Object = struct {...@@ -1068,7 +1068,7 @@ pub const Object = struct {
1068 name,1068 name,
1069 );1069 );
1070 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.1070 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
1071 try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(ptr_di_ty));1071 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(ptr_di_ty), .{ .target = o.target });
1072 return ptr_di_ty;1072 return ptr_di_ty;
1073 },1073 },
1074 .Opaque => {1074 .Opaque => {
...@@ -1077,7 +1077,7 @@ pub const Object = struct {...@@ -1077,7 +1077,7 @@ pub const Object = struct {
1077 gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_ty);1077 gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_ty);
1078 return di_ty;1078 return di_ty;
1079 }1079 }
1080 const name = try ty.nameAlloc(gpa);1080 const name = try ty.nameAlloc(gpa, target);
1081 defer gpa.free(name);1081 defer gpa.free(name);
1082 const owner_decl = ty.getOwnerDecl();1082 const owner_decl = ty.getOwnerDecl();
1083 const opaque_di_ty = dib.createForwardDeclType(1083 const opaque_di_ty = dib.createForwardDeclType(
...@@ -1089,7 +1089,7 @@ pub const Object = struct {...@@ -1089,7 +1089,7 @@ pub const Object = struct {
1089 );1089 );
1090 // The recursive call to `lowerDebugType` va `namespaceToDebugScope`1090 // The recursive call to `lowerDebugType` va `namespaceToDebugScope`
1091 // means we can't use `gop` anymore.1091 // means we can't use `gop` anymore.
1092 try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(opaque_di_ty));1092 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(opaque_di_ty), .{ .target = o.target });
1093 return opaque_di_ty;1093 return opaque_di_ty;
1094 },1094 },
1095 .Array => {1095 .Array => {
...@@ -1100,7 +1100,7 @@ pub const Object = struct {...@@ -1100,7 +1100,7 @@ pub const Object = struct {
1100 @intCast(c_int, ty.arrayLen()),1100 @intCast(c_int, ty.arrayLen()),
1101 );1101 );
1102 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.1102 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
1103 try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(array_di_ty));1103 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(array_di_ty), .{ .target = o.target });
1104 return array_di_ty;1104 return array_di_ty;
1105 },1105 },
1106 .Vector => {1106 .Vector => {
...@@ -1111,11 +1111,11 @@ pub const Object = struct {...@@ -1111,11 +1111,11 @@ pub const Object = struct {
1111 ty.vectorLen(),1111 ty.vectorLen(),
1112 );1112 );
1113 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.1113 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
1114 try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(vector_di_ty));1114 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(vector_di_ty), .{ .target = o.target });
1115 return vector_di_ty;1115 return vector_di_ty;
1116 },1116 },
1117 .Optional => {1117 .Optional => {
1118 const name = try ty.nameAlloc(gpa);1118 const name = try ty.nameAlloc(gpa, target);
1119 defer gpa.free(name);1119 defer gpa.free(name);
1120 var buf: Type.Payload.ElemType = undefined;1120 var buf: Type.Payload.ElemType = undefined;
1121 const child_ty = ty.optionalChild(&buf);1121 const child_ty = ty.optionalChild(&buf);
...@@ -1127,7 +1127,7 @@ pub const Object = struct {...@@ -1127,7 +1127,7 @@ pub const Object = struct {
1127 if (ty.isPtrLikeOptional()) {1127 if (ty.isPtrLikeOptional()) {
1128 const ptr_di_ty = try o.lowerDebugType(child_ty, resolve);1128 const ptr_di_ty = try o.lowerDebugType(child_ty, resolve);
1129 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.1129 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
1130 try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(ptr_di_ty));1130 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(ptr_di_ty), .{ .target = o.target });
1131 return ptr_di_ty;1131 return ptr_di_ty;
1132 }1132 }
11331133
...@@ -1200,7 +1200,7 @@ pub const Object = struct {...@@ -1200,7 +1200,7 @@ pub const Object = struct {
1200 );1200 );
1201 dib.replaceTemporary(fwd_decl, full_di_ty);1201 dib.replaceTemporary(fwd_decl, full_di_ty);
1202 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.1202 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
1203 try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty));1203 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty), .{ .target = o.target });
1204 return full_di_ty;1204 return full_di_ty;
1205 },1205 },
1206 .ErrorUnion => {1206 .ErrorUnion => {
...@@ -1209,10 +1209,10 @@ pub const Object = struct {...@@ -1209,10 +1209,10 @@ pub const Object = struct {
1209 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {1209 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
1210 const err_set_di_ty = try o.lowerDebugType(err_set_ty, .full);1210 const err_set_di_ty = try o.lowerDebugType(err_set_ty, .full);
1211 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.1211 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
1212 try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(err_set_di_ty));1212 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(err_set_di_ty), .{ .target = o.target });
1213 return err_set_di_ty;1213 return err_set_di_ty;
1214 }1214 }
1215 const name = try ty.nameAlloc(gpa);1215 const name = try ty.nameAlloc(gpa, target);
1216 defer gpa.free(name);1216 defer gpa.free(name);
1217 const di_file: ?*llvm.DIFile = null;1217 const di_file: ?*llvm.DIFile = null;
1218 const line = 0;1218 const line = 0;
...@@ -1282,7 +1282,7 @@ pub const Object = struct {...@@ -1282,7 +1282,7 @@ pub const Object = struct {
1282 );1282 );
1283 dib.replaceTemporary(fwd_decl, full_di_ty);1283 dib.replaceTemporary(fwd_decl, full_di_ty);
1284 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.1284 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
1285 try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty));1285 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty), .{ .target = o.target });
1286 return full_di_ty;1286 return full_di_ty;
1287 },1287 },
1288 .ErrorSet => {1288 .ErrorSet => {
...@@ -1294,7 +1294,7 @@ pub const Object = struct {...@@ -1294,7 +1294,7 @@ pub const Object = struct {
1294 },1294 },
1295 .Struct => {1295 .Struct => {
1296 const compile_unit_scope = o.di_compile_unit.?.toScope();1296 const compile_unit_scope = o.di_compile_unit.?.toScope();
1297 const name = try ty.nameAlloc(gpa);1297 const name = try ty.nameAlloc(gpa, target);
1298 defer gpa.free(name);1298 defer gpa.free(name);
12991299
1300 if (ty.castTag(.@"struct")) |payload| {1300 if (ty.castTag(.@"struct")) |payload| {
...@@ -1381,7 +1381,7 @@ pub const Object = struct {...@@ -1381,7 +1381,7 @@ pub const Object = struct {
1381 );1381 );
1382 dib.replaceTemporary(fwd_decl, full_di_ty);1382 dib.replaceTemporary(fwd_decl, full_di_ty);
1383 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.1383 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
1384 try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty));1384 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty), .{ .target = o.target });
1385 return full_di_ty;1385 return full_di_ty;
1386 }1386 }
13871387
...@@ -1395,7 +1395,7 @@ pub const Object = struct {...@@ -1395,7 +1395,7 @@ pub const Object = struct {
1395 dib.replaceTemporary(fwd_decl, struct_di_ty);1395 dib.replaceTemporary(fwd_decl, struct_di_ty);
1396 // The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType`1396 // The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType`
1397 // means we can't use `gop` anymore.1397 // means we can't use `gop` anymore.
1398 try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(struct_di_ty));1398 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(struct_di_ty), .{ .target = o.target });
1399 return struct_di_ty;1399 return struct_di_ty;
1400 }1400 }
1401 }1401 }
...@@ -1406,7 +1406,7 @@ pub const Object = struct {...@@ -1406,7 +1406,7 @@ pub const Object = struct {
1406 dib.replaceTemporary(fwd_decl, struct_di_ty);1406 dib.replaceTemporary(fwd_decl, struct_di_ty);
1407 // The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType`1407 // The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType`
1408 // means we can't use `gop` anymore.1408 // means we can't use `gop` anymore.
1409 try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(struct_di_ty));1409 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(struct_di_ty), .{ .target = o.target });
1410 return struct_di_ty;1410 return struct_di_ty;
1411 }1411 }
14121412
...@@ -1461,13 +1461,13 @@ pub const Object = struct {...@@ -1461,13 +1461,13 @@ pub const Object = struct {
1461 );1461 );
1462 dib.replaceTemporary(fwd_decl, full_di_ty);1462 dib.replaceTemporary(fwd_decl, full_di_ty);
1463 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.1463 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
1464 try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty));1464 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty), .{ .target = o.target });
1465 return full_di_ty;1465 return full_di_ty;
1466 },1466 },
1467 .Union => {1467 .Union => {
1468 const owner_decl = ty.getOwnerDecl();1468 const owner_decl = ty.getOwnerDecl();
14691469
1470 const name = try ty.nameAlloc(gpa);1470 const name = try ty.nameAlloc(gpa, target);
1471 defer gpa.free(name);1471 defer gpa.free(name);
14721472
1473 const fwd_decl = opt_fwd_decl orelse blk: {1473 const fwd_decl = opt_fwd_decl orelse blk: {
...@@ -1489,7 +1489,7 @@ pub const Object = struct {...@@ -1489,7 +1489,7 @@ pub const Object = struct {
1489 dib.replaceTemporary(fwd_decl, union_di_ty);1489 dib.replaceTemporary(fwd_decl, union_di_ty);
1490 // The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType`1490 // The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType`
1491 // means we can't use `gop` anymore.1491 // means we can't use `gop` anymore.
1492 try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(union_di_ty));1492 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(union_di_ty), .{ .target = o.target });
1493 return union_di_ty;1493 return union_di_ty;
1494 }1494 }
14951495
...@@ -1603,7 +1603,7 @@ pub const Object = struct {...@@ -1603,7 +1603,7 @@ pub const Object = struct {
1603 0,1603 0,
1604 );1604 );
1605 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.1605 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
1606 try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(fn_di_ty));1606 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(fn_di_ty), .{ .target = o.target });
1607 return fn_di_ty;1607 return fn_di_ty;
1608 },1608 },
1609 .ComptimeInt => unreachable,1609 .ComptimeInt => unreachable,
...@@ -1676,7 +1676,9 @@ pub const DeclGen = struct {...@@ -1676,7 +1676,9 @@ pub const DeclGen = struct {
1676 const decl = dg.decl;1676 const decl = dg.decl;
1677 assert(decl.has_tv);1677 assert(decl.has_tv);
16781678
1679 log.debug("gen: {s} type: {}, value: {}", .{ decl.name, decl.ty, decl.val.fmtDebug() });1679 log.debug("gen: {s} type: {}, value: {}", .{
1680 decl.name, decl.ty.fmtDebug(), decl.val.fmtDebug(),
1681 });
16801682
1681 if (decl.val.castTag(.function)) |func_payload| {1683 if (decl.val.castTag(.function)) |func_payload| {
1682 _ = func_payload;1684 _ = func_payload;
...@@ -1990,7 +1992,7 @@ pub const DeclGen = struct {...@@ -1990,7 +1992,7 @@ pub const DeclGen = struct {
1990 },1992 },
1991 .Opaque => switch (t.tag()) {1993 .Opaque => switch (t.tag()) {
1992 .@"opaque" => {1994 .@"opaque" => {
1993 const gop = try dg.object.type_map.getOrPut(gpa, t);1995 const gop = try dg.object.type_map.getOrPutContext(gpa, t, .{ .target = target });
1994 if (gop.found_existing) return gop.value_ptr.*;1996 if (gop.found_existing) return gop.value_ptr.*;
19951997
1996 // The Type memory is ephemeral; since we want to store a longer-lived1998 // The Type memory is ephemeral; since we want to store a longer-lived
...@@ -2051,7 +2053,7 @@ pub const DeclGen = struct {...@@ -2051,7 +2053,7 @@ pub const DeclGen = struct {
2051 return dg.context.intType(16);2053 return dg.context.intType(16);
2052 },2054 },
2053 .Struct => {2055 .Struct => {
2054 const gop = try dg.object.type_map.getOrPut(gpa, t);2056 const gop = try dg.object.type_map.getOrPutContext(gpa, t, .{ .target = target });
2055 if (gop.found_existing) return gop.value_ptr.*;2057 if (gop.found_existing) return gop.value_ptr.*;
20562058
2057 // The Type memory is ephemeral; since we want to store a longer-lived2059 // The Type memory is ephemeral; since we want to store a longer-lived
...@@ -2174,7 +2176,7 @@ pub const DeclGen = struct {...@@ -2174,7 +2176,7 @@ pub const DeclGen = struct {
2174 return llvm_struct_ty;2176 return llvm_struct_ty;
2175 },2177 },
2176 .Union => {2178 .Union => {
2177 const gop = try dg.object.type_map.getOrPut(gpa, t);2179 const gop = try dg.object.type_map.getOrPutContext(gpa, t, .{ .target = target });
2178 if (gop.found_existing) return gop.value_ptr.*;2180 if (gop.found_existing) return gop.value_ptr.*;
21792181
2180 // The Type memory is ephemeral; since we want to store a longer-lived2182 // The Type memory is ephemeral; since we want to store a longer-lived
...@@ -2289,6 +2291,7 @@ pub const DeclGen = struct {...@@ -2289,6 +2291,7 @@ pub const DeclGen = struct {
2289 const llvm_type = try dg.llvmType(tv.ty);2291 const llvm_type = try dg.llvmType(tv.ty);
2290 return llvm_type.getUndef();2292 return llvm_type.getUndef();
2291 }2293 }
2294 const target = dg.module.getTarget();
22922295
2293 switch (tv.ty.zigTypeTag()) {2296 switch (tv.ty.zigTypeTag()) {
2294 .Bool => {2297 .Bool => {
...@@ -2302,8 +2305,7 @@ pub const DeclGen = struct {...@@ -2302,8 +2305,7 @@ pub const DeclGen = struct {
2302 .decl_ref => return lowerDeclRefValue(dg, tv, tv.val.castTag(.decl_ref).?.data),2305 .decl_ref => return lowerDeclRefValue(dg, tv, tv.val.castTag(.decl_ref).?.data),
2303 else => {2306 else => {
2304 var bigint_space: Value.BigIntSpace = undefined;2307 var bigint_space: Value.BigIntSpace = undefined;
2305 const bigint = tv.val.toBigInt(&bigint_space);2308 const bigint = tv.val.toBigInt(&bigint_space, target);
2306 const target = dg.module.getTarget();
2307 const int_info = tv.ty.intInfo(target);2309 const int_info = tv.ty.intInfo(target);
2308 assert(int_info.bits != 0);2310 assert(int_info.bits != 0);
2309 const llvm_type = dg.context.intType(int_info.bits);2311 const llvm_type = dg.context.intType(int_info.bits);
...@@ -2331,9 +2333,8 @@ pub const DeclGen = struct {...@@ -2331,9 +2333,8 @@ pub const DeclGen = struct {
2331 const int_val = tv.enumToInt(&int_buffer);2333 const int_val = tv.enumToInt(&int_buffer);
23322334
2333 var bigint_space: Value.BigIntSpace = undefined;2335 var bigint_space: Value.BigIntSpace = undefined;
2334 const bigint = int_val.toBigInt(&bigint_space);2336 const bigint = int_val.toBigInt(&bigint_space, target);
23352337
2336 const target = dg.module.getTarget();
2337 const int_info = tv.ty.intInfo(target);2338 const int_info = tv.ty.intInfo(target);
2338 const llvm_type = dg.context.intType(int_info.bits);2339 const llvm_type = dg.context.intType(int_info.bits);
23392340
...@@ -2356,7 +2357,6 @@ pub const DeclGen = struct {...@@ -2356,7 +2357,6 @@ pub const DeclGen = struct {
2356 },2357 },
2357 .Float => {2358 .Float => {
2358 const llvm_ty = try dg.llvmType(tv.ty);2359 const llvm_ty = try dg.llvmType(tv.ty);
2359 const target = dg.module.getTarget();
2360 switch (tv.ty.floatBits(target)) {2360 switch (tv.ty.floatBits(target)) {
2361 16, 32, 64 => return llvm_ty.constReal(tv.val.toFloat(f64)),2361 16, 32, 64 => return llvm_ty.constReal(tv.val.toFloat(f64)),
2362 80 => {2362 80 => {
...@@ -2414,7 +2414,7 @@ pub const DeclGen = struct {...@@ -2414,7 +2414,7 @@ pub const DeclGen = struct {
2414 },2414 },
2415 .int_u64, .one, .int_big_positive => {2415 .int_u64, .one, .int_big_positive => {
2416 const llvm_usize = try dg.llvmType(Type.usize);2416 const llvm_usize = try dg.llvmType(Type.usize);
2417 const llvm_int = llvm_usize.constInt(tv.val.toUnsignedInt(), .False);2417 const llvm_int = llvm_usize.constInt(tv.val.toUnsignedInt(target), .False);
2418 return llvm_int.constIntToPtr(try dg.llvmType(tv.ty));2418 return llvm_int.constIntToPtr(try dg.llvmType(tv.ty));
2419 },2419 },
2420 .field_ptr, .opt_payload_ptr, .eu_payload_ptr, .elem_ptr => {2420 .field_ptr, .opt_payload_ptr, .eu_payload_ptr, .elem_ptr => {
...@@ -2424,7 +2424,9 @@ pub const DeclGen = struct {...@@ -2424,7 +2424,9 @@ pub const DeclGen = struct {
2424 const llvm_type = try dg.llvmType(tv.ty);2424 const llvm_type = try dg.llvmType(tv.ty);
2425 return llvm_type.constNull();2425 return llvm_type.constNull();
2426 },2426 },
2427 else => |tag| return dg.todo("implement const of pointer type '{}' ({})", .{ tv.ty, tag }),2427 else => |tag| return dg.todo("implement const of pointer type '{}' ({})", .{
2428 tv.ty.fmtDebug(), tag,
2429 }),
2428 },2430 },
2429 .Array => switch (tv.val.tag()) {2431 .Array => switch (tv.val.tag()) {
2430 .bytes => {2432 .bytes => {
...@@ -2592,7 +2594,6 @@ pub const DeclGen = struct {...@@ -2592,7 +2594,6 @@ pub const DeclGen = struct {
2592 const llvm_struct_ty = try dg.llvmType(tv.ty);2594 const llvm_struct_ty = try dg.llvmType(tv.ty);
2593 const field_vals = tv.val.castTag(.aggregate).?.data;2595 const field_vals = tv.val.castTag(.aggregate).?.data;
2594 const gpa = dg.gpa;2596 const gpa = dg.gpa;
2595 const target = dg.module.getTarget();
25962597
2597 if (tv.ty.isTupleOrAnonStruct()) {2598 if (tv.ty.isTupleOrAnonStruct()) {
2598 const tuple = tv.ty.tupleFields();2599 const tuple = tv.ty.tupleFields();
...@@ -2753,7 +2754,6 @@ pub const DeclGen = struct {...@@ -2753,7 +2754,6 @@ pub const DeclGen = struct {
2753 const llvm_union_ty = try dg.llvmType(tv.ty);2754 const llvm_union_ty = try dg.llvmType(tv.ty);
2754 const tag_and_val = tv.val.castTag(.@"union").?.data;2755 const tag_and_val = tv.val.castTag(.@"union").?.data;
27552756
2756 const target = dg.module.getTarget();
2757 const layout = tv.ty.unionGetLayout(target);2757 const layout = tv.ty.unionGetLayout(target);
27582758
2759 if (layout.payload_size == 0) {2759 if (layout.payload_size == 0) {
...@@ -2763,7 +2763,7 @@ pub const DeclGen = struct {...@@ -2763,7 +2763,7 @@ pub const DeclGen = struct {
2763 });2763 });
2764 }2764 }
2765 const union_obj = tv.ty.cast(Type.Payload.Union).?.data;2765 const union_obj = tv.ty.cast(Type.Payload.Union).?.data;
2766 const field_index = union_obj.tag_ty.enumTagFieldIndex(tag_and_val.tag).?;2766 const field_index = union_obj.tag_ty.enumTagFieldIndex(tag_and_val.tag, target).?;
2767 assert(union_obj.haveFieldTypes());2767 assert(union_obj.haveFieldTypes());
2768 const field_ty = union_obj.fields.values()[field_index].ty;2768 const field_ty = union_obj.fields.values()[field_index].ty;
2769 const payload = p: {2769 const payload = p: {
...@@ -2892,7 +2892,7 @@ pub const DeclGen = struct {...@@ -2892,7 +2892,7 @@ pub const DeclGen = struct {
28922892
2893 .Frame,2893 .Frame,
2894 .AnyFrame,2894 .AnyFrame,
2895 => return dg.todo("implement const of type '{}'", .{tv.ty}),2895 => return dg.todo("implement const of type '{}'", .{tv.ty.fmtDebug()}),
2896 }2896 }
2897 }2897 }
28982898
...@@ -2910,7 +2910,8 @@ pub const DeclGen = struct {...@@ -2910,7 +2910,8 @@ pub const DeclGen = struct {
2910 const ptr_ty = Type.initPayload(&ptr_ty_payload.base);2910 const ptr_ty = Type.initPayload(&ptr_ty_payload.base);
2911 const llvm_ptr = try dg.lowerDeclRefValue(.{ .ty = ptr_ty, .val = ptr_val }, decl);2911 const llvm_ptr = try dg.lowerDeclRefValue(.{ .ty = ptr_ty, .val = ptr_val }, decl);
29122912
2913 if (ptr_child_ty.eql(decl.ty)) {2913 const target = dg.module.getTarget();
2914 if (ptr_child_ty.eql(decl.ty, target)) {
2914 return llvm_ptr;2915 return llvm_ptr;
2915 } else {2916 } else {
2916 return llvm_ptr.constBitCast((try dg.llvmType(ptr_child_ty)).pointerType(0));2917 return llvm_ptr.constBitCast((try dg.llvmType(ptr_child_ty)).pointerType(0));
...@@ -2918,6 +2919,7 @@ pub const DeclGen = struct {...@@ -2918,6 +2919,7 @@ pub const DeclGen = struct {
2918 }2919 }
29192920
2920 fn lowerParentPtr(dg: *DeclGen, ptr_val: Value, ptr_child_ty: Type) Error!*const llvm.Value {2921 fn lowerParentPtr(dg: *DeclGen, ptr_val: Value, ptr_child_ty: Type) Error!*const llvm.Value {
2922 const target = dg.module.getTarget();
2921 var bitcast_needed: bool = undefined;2923 var bitcast_needed: bool = undefined;
2922 const llvm_ptr = switch (ptr_val.tag()) {2924 const llvm_ptr = switch (ptr_val.tag()) {
2923 .decl_ref_mut => {2925 .decl_ref_mut => {
...@@ -2951,7 +2953,6 @@ pub const DeclGen = struct {...@@ -2951,7 +2953,6 @@ pub const DeclGen = struct {
29512953
2952 const field_index = @intCast(u32, field_ptr.field_index);2954 const field_index = @intCast(u32, field_ptr.field_index);
2953 const llvm_u32 = dg.context.intType(32);2955 const llvm_u32 = dg.context.intType(32);
2954 const target = dg.module.getTarget();
2955 switch (parent_ty.zigTypeTag()) {2956 switch (parent_ty.zigTypeTag()) {
2956 .Union => {2957 .Union => {
2957 bitcast_needed = true;2958 bitcast_needed = true;
...@@ -2974,7 +2975,7 @@ pub const DeclGen = struct {...@@ -2974,7 +2975,7 @@ pub const DeclGen = struct {
2974 },2975 },
2975 .Struct => {2976 .Struct => {
2976 const field_ty = parent_ty.structFieldType(field_index);2977 const field_ty = parent_ty.structFieldType(field_index);
2977 bitcast_needed = !field_ty.eql(ptr_child_ty);2978 bitcast_needed = !field_ty.eql(ptr_child_ty, target);
29782979
2979 var ty_buf: Type.Payload.Pointer = undefined;2980 var ty_buf: Type.Payload.Pointer = undefined;
2980 const llvm_field_index = llvmFieldIndex(parent_ty, field_index, target, &ty_buf).?;2981 const llvm_field_index = llvmFieldIndex(parent_ty, field_index, target, &ty_buf).?;
...@@ -2990,7 +2991,7 @@ pub const DeclGen = struct {...@@ -2990,7 +2991,7 @@ pub const DeclGen = struct {
2990 .elem_ptr => blk: {2991 .elem_ptr => blk: {
2991 const elem_ptr = ptr_val.castTag(.elem_ptr).?.data;2992 const elem_ptr = ptr_val.castTag(.elem_ptr).?.data;
2992 const parent_llvm_ptr = try dg.lowerParentPtr(elem_ptr.array_ptr, elem_ptr.elem_ty);2993 const parent_llvm_ptr = try dg.lowerParentPtr(elem_ptr.array_ptr, elem_ptr.elem_ty);
2993 bitcast_needed = !elem_ptr.elem_ty.eql(ptr_child_ty);2994 bitcast_needed = !elem_ptr.elem_ty.eql(ptr_child_ty, target);
29942995
2995 const llvm_usize = try dg.llvmType(Type.usize);2996 const llvm_usize = try dg.llvmType(Type.usize);
2996 const indices: [1]*const llvm.Value = .{2997 const indices: [1]*const llvm.Value = .{
...@@ -3004,7 +3005,7 @@ pub const DeclGen = struct {...@@ -3004,7 +3005,7 @@ pub const DeclGen = struct {
3004 var buf: Type.Payload.ElemType = undefined;3005 var buf: Type.Payload.ElemType = undefined;
30053006
3006 const payload_ty = opt_payload_ptr.container_ty.optionalChild(&buf);3007 const payload_ty = opt_payload_ptr.container_ty.optionalChild(&buf);
3007 bitcast_needed = !payload_ty.eql(ptr_child_ty);3008 bitcast_needed = !payload_ty.eql(ptr_child_ty, target);
30083009
3009 if (!payload_ty.hasRuntimeBitsIgnoreComptime() or payload_ty.isPtrLikeOptional()) {3010 if (!payload_ty.hasRuntimeBitsIgnoreComptime() or payload_ty.isPtrLikeOptional()) {
3010 // In this case, we represent pointer to optional the same as pointer3011 // In this case, we represent pointer to optional the same as pointer
...@@ -3024,7 +3025,7 @@ pub const DeclGen = struct {...@@ -3024,7 +3025,7 @@ pub const DeclGen = struct {
3024 const parent_llvm_ptr = try dg.lowerParentPtr(eu_payload_ptr.container_ptr, eu_payload_ptr.container_ty);3025 const parent_llvm_ptr = try dg.lowerParentPtr(eu_payload_ptr.container_ptr, eu_payload_ptr.container_ty);
30253026
3026 const payload_ty = eu_payload_ptr.container_ty.errorUnionPayload();3027 const payload_ty = eu_payload_ptr.container_ty.errorUnionPayload();
3027 bitcast_needed = !payload_ty.eql(ptr_child_ty);3028 bitcast_needed = !payload_ty.eql(ptr_child_ty, target);
30283029
3029 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {3030 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
3030 // In this case, we represent pointer to error union the same as pointer3031 // In this case, we represent pointer to error union the same as pointer
...@@ -3053,12 +3054,13 @@ pub const DeclGen = struct {...@@ -3053,12 +3054,13 @@ pub const DeclGen = struct {
3053 tv: TypedValue,3054 tv: TypedValue,
3054 decl: *Module.Decl,3055 decl: *Module.Decl,
3055 ) Error!*const llvm.Value {3056 ) Error!*const llvm.Value {
3057 const target = self.module.getTarget();
3056 if (tv.ty.isSlice()) {3058 if (tv.ty.isSlice()) {
3057 var buf: Type.SlicePtrFieldTypeBuffer = undefined;3059 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
3058 const ptr_ty = tv.ty.slicePtrFieldType(&buf);3060 const ptr_ty = tv.ty.slicePtrFieldType(&buf);
3059 var slice_len: Value.Payload.U64 = .{3061 var slice_len: Value.Payload.U64 = .{
3060 .base = .{ .tag = .int_u64 },3062 .base = .{ .tag = .int_u64 },
3061 .data = tv.val.sliceLen(),3063 .data = tv.val.sliceLen(target),
3062 };3064 };
3063 const fields: [2]*const llvm.Value = .{3065 const fields: [2]*const llvm.Value = .{
3064 try self.genTypedValue(.{3066 try self.genTypedValue(.{
src/codegen/spirv.zig+10-8
...@@ -313,7 +313,7 @@ pub const DeclGen = struct {...@@ -313,7 +313,7 @@ pub const DeclGen = struct {
313 // As of yet, there is no vector support in the self-hosted compiler.313 // As of yet, there is no vector support in the self-hosted compiler.
314 .Vector => self.todo("implement arithmeticTypeInfo for Vector", .{}),314 .Vector => self.todo("implement arithmeticTypeInfo for Vector", .{}),
315 // TODO: For which types is this the case?315 // TODO: For which types is this the case?
316 else => self.todo("implement arithmeticTypeInfo for {}", .{ty}),316 else => self.todo("implement arithmeticTypeInfo for {}", .{ty.fmtDebug()}),
317 };317 };
318 }318 }
319319
...@@ -335,7 +335,7 @@ pub const DeclGen = struct {...@@ -335,7 +335,7 @@ pub const DeclGen = struct {
335 const int_info = ty.intInfo(target);335 const int_info = ty.intInfo(target);
336 const backing_bits = self.backingIntBits(int_info.bits) orelse {336 const backing_bits = self.backingIntBits(int_info.bits) orelse {
337 // Integers too big for any native type are represented as "composite integers": An array of largestSupportedIntBits.337 // Integers too big for any native type are represented as "composite integers": An array of largestSupportedIntBits.
338 return self.todo("implement composite int constants for {}", .{ty});338 return self.todo("implement composite int constants for {}", .{ty.fmtDebug()});
339 };339 };
340340
341 // We can just use toSignedInt/toUnsignedInt here as it returns u64 - a type large enough to hold any341 // We can just use toSignedInt/toUnsignedInt here as it returns u64 - a type large enough to hold any
...@@ -345,7 +345,7 @@ pub const DeclGen = struct {...@@ -345,7 +345,7 @@ pub const DeclGen = struct {
345345
346 // Note, value is required to be sign-extended, so we don't need to mask off the upper bits.346 // Note, value is required to be sign-extended, so we don't need to mask off the upper bits.
347 // See https://www.khronos.org/registry/SPIR-V/specs/unified1/SPIRV.html#Literal347 // See https://www.khronos.org/registry/SPIR-V/specs/unified1/SPIRV.html#Literal
348 var int_bits = if (ty.isSignedInt()) @bitCast(u64, val.toSignedInt()) else val.toUnsignedInt();348 var int_bits = if (ty.isSignedInt()) @bitCast(u64, val.toSignedInt()) else val.toUnsignedInt(target);
349349
350 const value: spec.LiteralContextDependentNumber = switch (backing_bits) {350 const value: spec.LiteralContextDependentNumber = switch (backing_bits) {
351 1...32 => .{ .uint32 = @truncate(u32, int_bits) },351 1...32 => .{ .uint32 = @truncate(u32, int_bits) },
...@@ -388,7 +388,7 @@ pub const DeclGen = struct {...@@ -388,7 +388,7 @@ pub const DeclGen = struct {
388 });388 });
389 },389 },
390 .Void => unreachable,390 .Void => unreachable,
391 else => return self.todo("constant generation of type {}", .{ty}),391 else => return self.todo("constant generation of type {}", .{ty.fmtDebug()}),
392 }392 }
393393
394 return result_id.toRef();394 return result_id.toRef();
...@@ -414,7 +414,7 @@ pub const DeclGen = struct {...@@ -414,7 +414,7 @@ pub const DeclGen = struct {
414 const backing_bits = self.backingIntBits(int_info.bits) orelse {414 const backing_bits = self.backingIntBits(int_info.bits) orelse {
415 // TODO: Integers too big for any native type are represented as "composite integers":415 // TODO: Integers too big for any native type are represented as "composite integers":
416 // An array of largestSupportedIntBits.416 // An array of largestSupportedIntBits.
417 return self.todo("Implement composite int type {}", .{ty});417 return self.todo("Implement composite int type {}", .{ty.fmtDebug()});
418 };418 };
419419
420 const payload = try self.spv.arena.create(SpvType.Payload.Int);420 const payload = try self.spv.arena.create(SpvType.Payload.Int);
...@@ -644,8 +644,10 @@ pub const DeclGen = struct {...@@ -644,8 +644,10 @@ pub const DeclGen = struct {
644 const result_id = self.spv.allocId();644 const result_id = self.spv.allocId();
645 const result_type_id = try self.resolveTypeId(ty);645 const result_type_id = try self.resolveTypeId(ty);
646646
647 assert(self.air.typeOf(bin_op.lhs).eql(ty));647 const target = self.getTarget();
648 assert(self.air.typeOf(bin_op.rhs).eql(ty));648
649 assert(self.air.typeOf(bin_op.lhs).eql(ty, target));
650 assert(self.air.typeOf(bin_op.rhs).eql(ty, target));
649651
650 // Binary operations are generally applicable to both scalar and vector operations652 // Binary operations are generally applicable to both scalar and vector operations
651 // in SPIR-V, but int and float versions of operations require different opcodes.653 // in SPIR-V, but int and float versions of operations require different opcodes.
...@@ -692,7 +694,7 @@ pub const DeclGen = struct {...@@ -692,7 +694,7 @@ pub const DeclGen = struct {
692 const result_id = self.spv.allocId();694 const result_id = self.spv.allocId();
693 const result_type_id = try self.resolveTypeId(Type.initTag(.bool));695 const result_type_id = try self.resolveTypeId(Type.initTag(.bool));
694 const op_ty = self.air.typeOf(bin_op.lhs);696 const op_ty = self.air.typeOf(bin_op.lhs);
695 assert(op_ty.eql(self.air.typeOf(bin_op.rhs)));697 assert(op_ty.eql(self.air.typeOf(bin_op.rhs), self.getTarget()));
696698
697 // Comparisons are generally applicable to both scalar and vector operations in SPIR-V,699 // Comparisons are generally applicable to both scalar and vector operations in SPIR-V,
698 // but int and float versions of operations require different opcodes.700 // but int and float versions of operations require different opcodes.
src/link.zig+2-2
...@@ -457,7 +457,7 @@ pub const File = struct {...@@ -457,7 +457,7 @@ pub const File = struct {
457 /// May be called before or after updateDeclExports but must be called457 /// May be called before or after updateDeclExports but must be called
458 /// after allocateDeclIndexes for any given Decl.458 /// after allocateDeclIndexes for any given Decl.
459 pub fn updateDecl(base: *File, module: *Module, decl: *Module.Decl) UpdateDeclError!void {459 pub fn updateDecl(base: *File, module: *Module, decl: *Module.Decl) UpdateDeclError!void {
460 log.debug("updateDecl {*} ({s}), type={}", .{ decl, decl.name, decl.ty });460 log.debug("updateDecl {*} ({s}), type={}", .{ decl, decl.name, decl.ty.fmtDebug() });
461 assert(decl.has_tv);461 assert(decl.has_tv);
462 switch (base.tag) {462 switch (base.tag) {
463 // zig fmt: off463 // zig fmt: off
...@@ -477,7 +477,7 @@ pub const File = struct {...@@ -477,7 +477,7 @@ pub const File = struct {
477 /// after allocateDeclIndexes for any given Decl.477 /// after allocateDeclIndexes for any given Decl.
478 pub fn updateFunc(base: *File, module: *Module, func: *Module.Fn, air: Air, liveness: Liveness) UpdateDeclError!void {478 pub fn updateFunc(base: *File, module: *Module, func: *Module.Fn, air: Air, liveness: Liveness) UpdateDeclError!void {
479 log.debug("updateFunc {*} ({s}), type={}", .{479 log.debug("updateFunc {*} ({s}), type={}", .{
480 func.owner_decl, func.owner_decl.name, func.owner_decl.ty,480 func.owner_decl, func.owner_decl.name, func.owner_decl.ty.fmtDebug(),
481 });481 });
482 switch (base.tag) {482 switch (base.tag) {
483 // zig fmt: off483 // zig fmt: off
src/link/C.zig+5-3
...@@ -127,7 +127,7 @@ pub fn updateFunc(self: *C, module: *Module, func: *Module.Fn, air: Air, livenes...@@ -127,7 +127,7 @@ pub fn updateFunc(self: *C, module: *Module, func: *Module.Fn, air: Air, livenes
127 .error_msg = null,127 .error_msg = null,
128 .decl = decl,128 .decl = decl,
129 .fwd_decl = fwd_decl.toManaged(module.gpa),129 .fwd_decl = fwd_decl.toManaged(module.gpa),
130 .typedefs = typedefs.promote(module.gpa),130 .typedefs = typedefs.promoteContext(module.gpa, .{ .target = module.getTarget() }),
131 .typedefs_arena = self.arena.allocator(),131 .typedefs_arena = self.arena.allocator(),
132 },132 },
133 .code = code.toManaged(module.gpa),133 .code = code.toManaged(module.gpa),
...@@ -192,7 +192,7 @@ pub fn updateDecl(self: *C, module: *Module, decl: *Module.Decl) !void {...@@ -192,7 +192,7 @@ pub fn updateDecl(self: *C, module: *Module, decl: *Module.Decl) !void {
192 .error_msg = null,192 .error_msg = null,
193 .decl = decl,193 .decl = decl,
194 .fwd_decl = fwd_decl.toManaged(module.gpa),194 .fwd_decl = fwd_decl.toManaged(module.gpa),
195 .typedefs = typedefs.promote(module.gpa),195 .typedefs = typedefs.promoteContext(module.gpa, .{ .target = module.getTarget() }),
196 .typedefs_arena = self.arena.allocator(),196 .typedefs_arena = self.arena.allocator(),
197 },197 },
198 .code = code.toManaged(module.gpa),198 .code = code.toManaged(module.gpa),
...@@ -366,7 +366,9 @@ fn flushDecl(self: *C, f: *Flush, decl: *const Module.Decl) FlushDeclError!void...@@ -366,7 +366,9 @@ fn flushDecl(self: *C, f: *Flush, decl: *const Module.Decl) FlushDeclError!void
366 try f.typedefs.ensureUnusedCapacity(gpa, @intCast(u32, decl_block.typedefs.count()));366 try f.typedefs.ensureUnusedCapacity(gpa, @intCast(u32, decl_block.typedefs.count()));
367 var it = decl_block.typedefs.iterator();367 var it = decl_block.typedefs.iterator();
368 while (it.next()) |new| {368 while (it.next()) |new| {
369 const gop = f.typedefs.getOrPutAssumeCapacity(new.key_ptr.*);369 const gop = f.typedefs.getOrPutAssumeCapacityContext(new.key_ptr.*, .{
370 .target = self.base.options.target,
371 });
370 if (!gop.found_existing) {372 if (!gop.found_existing) {
371 try f.err_typedef_buf.appendSlice(gpa, new.value_ptr.rendered);373 try f.err_typedef_buf.appendSlice(gpa, new.value_ptr.rendered);
372 }374 }
src/link/Dwarf.zig+15-9
...@@ -200,7 +200,9 @@ pub fn initDeclDebugInfo(self: *Dwarf, decl: *Module.Decl) !DeclDebugBuffers {...@@ -200,7 +200,9 @@ pub fn initDeclDebugInfo(self: *Dwarf, decl: *Module.Decl) !DeclDebugBuffers {
200 assert(self.getRelocDbgInfoSubprogramHighPC() == dbg_info_buffer.items.len);200 assert(self.getRelocDbgInfoSubprogramHighPC() == dbg_info_buffer.items.len);
201 dbg_info_buffer.items.len += 4; // DW.AT.high_pc, DW.FORM.data4201 dbg_info_buffer.items.len += 4; // DW.AT.high_pc, DW.FORM.data4
202 if (fn_ret_has_bits) {202 if (fn_ret_has_bits) {
203 const gop = try dbg_info_type_relocs.getOrPut(gpa, fn_ret_type);203 const gop = try dbg_info_type_relocs.getOrPutContext(gpa, fn_ret_type, .{
204 .target = self.target,
205 });
204 if (!gop.found_existing) {206 if (!gop.found_existing) {
205 gop.value_ptr.* = .{207 gop.value_ptr.* = .{
206 .off = undefined,208 .off = undefined,
...@@ -455,7 +457,9 @@ pub fn commitDeclDebugInfo(...@@ -455,7 +457,9 @@ pub fn commitDeclDebugInfo(
455 var it: usize = 0;457 var it: usize = 0;
456 while (it < dbg_info_type_relocs.count()) : (it += 1) {458 while (it < dbg_info_type_relocs.count()) : (it += 1) {
457 const ty = dbg_info_type_relocs.keys()[it];459 const ty = dbg_info_type_relocs.keys()[it];
458 const value_ptr = dbg_info_type_relocs.getPtr(ty).?;460 const value_ptr = dbg_info_type_relocs.getPtrContext(ty, .{
461 .target = self.target,
462 }).?;
459 value_ptr.off = @intCast(u32, dbg_info_buffer.items.len);463 value_ptr.off = @intCast(u32, dbg_info_buffer.items.len);
460 try self.addDbgInfoType(dbg_type_arena.allocator(), ty, dbg_info_buffer, dbg_info_type_relocs);464 try self.addDbgInfoType(dbg_type_arena.allocator(), ty, dbg_info_buffer, dbg_info_type_relocs);
461 }465 }
...@@ -774,7 +778,7 @@ fn addDbgInfoType(...@@ -774,7 +778,7 @@ fn addDbgInfoType(
774 // DW.AT.byte_size, DW.FORM.data1778 // DW.AT.byte_size, DW.FORM.data1
775 dbg_info_buffer.appendAssumeCapacity(@intCast(u8, ty.abiSize(target)));779 dbg_info_buffer.appendAssumeCapacity(@intCast(u8, ty.abiSize(target)));
776 // DW.AT.name, DW.FORM.string780 // DW.AT.name, DW.FORM.string
777 try dbg_info_buffer.writer().print("{}\x00", .{ty});781 try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(target)});
778 },782 },
779 .Optional => {783 .Optional => {
780 if (ty.isPtrLikeOptional()) {784 if (ty.isPtrLikeOptional()) {
...@@ -785,7 +789,7 @@ fn addDbgInfoType(...@@ -785,7 +789,7 @@ fn addDbgInfoType(
785 // DW.AT.byte_size, DW.FORM.data1789 // DW.AT.byte_size, DW.FORM.data1
786 dbg_info_buffer.appendAssumeCapacity(@intCast(u8, ty.abiSize(target)));790 dbg_info_buffer.appendAssumeCapacity(@intCast(u8, ty.abiSize(target)));
787 // DW.AT.name, DW.FORM.string791 // DW.AT.name, DW.FORM.string
788 try dbg_info_buffer.writer().print("{}\x00", .{ty});792 try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(target)});
789 } else {793 } else {
790 // Non-pointer optionals are structs: struct { .maybe = *, .val = * }794 // Non-pointer optionals are structs: struct { .maybe = *, .val = * }
791 var buf = try arena.create(Type.Payload.ElemType);795 var buf = try arena.create(Type.Payload.ElemType);
...@@ -796,7 +800,7 @@ fn addDbgInfoType(...@@ -796,7 +800,7 @@ fn addDbgInfoType(
796 const abi_size = ty.abiSize(target);800 const abi_size = ty.abiSize(target);
797 try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size);801 try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size);
798 // DW.AT.name, DW.FORM.string802 // DW.AT.name, DW.FORM.string
799 try dbg_info_buffer.writer().print("{}\x00", .{ty});803 try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(target)});
800 // DW.AT.member804 // DW.AT.member
801 try dbg_info_buffer.ensureUnusedCapacity(7);805 try dbg_info_buffer.ensureUnusedCapacity(7);
802 dbg_info_buffer.appendAssumeCapacity(abbrev_struct_member);806 dbg_info_buffer.appendAssumeCapacity(abbrev_struct_member);
...@@ -835,7 +839,7 @@ fn addDbgInfoType(...@@ -835,7 +839,7 @@ fn addDbgInfoType(
835 // DW.AT.byte_size, DW.FORM.sdata839 // DW.AT.byte_size, DW.FORM.sdata
836 dbg_info_buffer.appendAssumeCapacity(@sizeOf(usize) * 2);840 dbg_info_buffer.appendAssumeCapacity(@sizeOf(usize) * 2);
837 // DW.AT.name, DW.FORM.string841 // DW.AT.name, DW.FORM.string
838 try dbg_info_buffer.writer().print("{}\x00", .{ty});842 try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(target)});
839 // DW.AT.member843 // DW.AT.member
840 try dbg_info_buffer.ensureUnusedCapacity(5);844 try dbg_info_buffer.ensureUnusedCapacity(5);
841 dbg_info_buffer.appendAssumeCapacity(abbrev_struct_member);845 dbg_info_buffer.appendAssumeCapacity(abbrev_struct_member);
...@@ -882,7 +886,7 @@ fn addDbgInfoType(...@@ -882,7 +886,7 @@ fn addDbgInfoType(
882 const abi_size = ty.abiSize(target);886 const abi_size = ty.abiSize(target);
883 try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size);887 try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size);
884 // DW.AT.name, DW.FORM.string888 // DW.AT.name, DW.FORM.string
885 const struct_name = try ty.nameAllocArena(arena);889 const struct_name = try ty.nameAllocArena(arena, target);
886 try dbg_info_buffer.ensureUnusedCapacity(struct_name.len + 1);890 try dbg_info_buffer.ensureUnusedCapacity(struct_name.len + 1);
887 dbg_info_buffer.appendSliceAssumeCapacity(struct_name);891 dbg_info_buffer.appendSliceAssumeCapacity(struct_name);
888 dbg_info_buffer.appendAssumeCapacity(0);892 dbg_info_buffer.appendAssumeCapacity(0);
...@@ -915,13 +919,15 @@ fn addDbgInfoType(...@@ -915,13 +919,15 @@ fn addDbgInfoType(
915 try dbg_info_buffer.append(0);919 try dbg_info_buffer.append(0);
916 },920 },
917 else => {921 else => {
918 log.debug("TODO implement .debug_info for type '{}'", .{ty});922 log.debug("TODO implement .debug_info for type '{}'", .{ty.fmtDebug()});
919 try dbg_info_buffer.append(abbrev_pad1);923 try dbg_info_buffer.append(abbrev_pad1);
920 },924 },
921 }925 }
922926
923 for (relocs.items) |rel| {927 for (relocs.items) |rel| {
924 const gop = try dbg_info_type_relocs.getOrPut(self.allocator, rel.ty);928 const gop = try dbg_info_type_relocs.getOrPutContext(self.allocator, rel.ty, .{
929 .target = self.target,
930 });
925 if (!gop.found_existing) {931 if (!gop.found_existing) {
926 gop.value_ptr.* = .{932 gop.value_ptr.* = .{
927 .off = undefined,933 .off = undefined,
src/link/MachO.zig+10-9
...@@ -3874,7 +3874,7 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void {...@@ -3874,7 +3874,7 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void {
38743874
3875/// Checks if the value, or any of its embedded values stores a pointer, and thus requires3875/// Checks if the value, or any of its embedded values stores a pointer, and thus requires
3876/// a rebase opcode for the dynamic linker.3876/// a rebase opcode for the dynamic linker.
3877fn needsPointerRebase(ty: Type, val: Value) bool {3877fn needsPointerRebase(ty: Type, val: Value, target: std.Target) bool {
3878 if (ty.zigTypeTag() == .Fn) {3878 if (ty.zigTypeTag() == .Fn) {
3879 return false;3879 return false;
3880 }3880 }
...@@ -3890,7 +3890,7 @@ fn needsPointerRebase(ty: Type, val: Value) bool {...@@ -3890,7 +3890,7 @@ fn needsPointerRebase(ty: Type, val: Value) bool {
3890 const elem_ty = ty.childType();3890 const elem_ty = ty.childType();
3891 var elem_value_buf: Value.ElemValueBuffer = undefined;3891 var elem_value_buf: Value.ElemValueBuffer = undefined;
3892 const elem_val = val.elemValueBuffer(0, &elem_value_buf);3892 const elem_val = val.elemValueBuffer(0, &elem_value_buf);
3893 return needsPointerRebase(elem_ty, elem_val);3893 return needsPointerRebase(elem_ty, elem_val, target);
3894 },3894 },
3895 .Struct => {3895 .Struct => {
3896 const fields = ty.structFields().values();3896 const fields = ty.structFields().values();
...@@ -3898,7 +3898,7 @@ fn needsPointerRebase(ty: Type, val: Value) bool {...@@ -3898,7 +3898,7 @@ fn needsPointerRebase(ty: Type, val: Value) bool {
3898 if (val.castTag(.aggregate)) |payload| {3898 if (val.castTag(.aggregate)) |payload| {
3899 const field_values = payload.data;3899 const field_values = payload.data;
3900 for (field_values) |field_val, i| {3900 for (field_values) |field_val, i| {
3901 if (needsPointerRebase(fields[i].ty, field_val)) return true;3901 if (needsPointerRebase(fields[i].ty, field_val, target)) return true;
3902 } else return false;3902 } else return false;
3903 } else return false;3903 } else return false;
3904 },3904 },
...@@ -3907,18 +3907,18 @@ fn needsPointerRebase(ty: Type, val: Value) bool {...@@ -3907,18 +3907,18 @@ fn needsPointerRebase(ty: Type, val: Value) bool {
3907 const sub_val = payload.data;3907 const sub_val = payload.data;
3908 var buffer: Type.Payload.ElemType = undefined;3908 var buffer: Type.Payload.ElemType = undefined;
3909 const sub_ty = ty.optionalChild(&buffer);3909 const sub_ty = ty.optionalChild(&buffer);
3910 return needsPointerRebase(sub_ty, sub_val);3910 return needsPointerRebase(sub_ty, sub_val, target);
3911 } else return false;3911 } else return false;
3912 },3912 },
3913 .Union => {3913 .Union => {
3914 const union_obj = val.cast(Value.Payload.Union).?.data;3914 const union_obj = val.cast(Value.Payload.Union).?.data;
3915 const active_field_ty = ty.unionFieldType(union_obj.tag);3915 const active_field_ty = ty.unionFieldType(union_obj.tag, target);
3916 return needsPointerRebase(active_field_ty, union_obj.val);3916 return needsPointerRebase(active_field_ty, union_obj.val, target);
3917 },3917 },
3918 .ErrorUnion => {3918 .ErrorUnion => {
3919 if (val.castTag(.eu_payload)) |payload| {3919 if (val.castTag(.eu_payload)) |payload| {
3920 const payload_ty = ty.errorUnionPayload();3920 const payload_ty = ty.errorUnionPayload();
3921 return needsPointerRebase(payload_ty, payload.data);3921 return needsPointerRebase(payload_ty, payload.data, target);
3922 } else return false;3922 } else return false;
3923 },3923 },
3924 else => return false,3924 else => return false,
...@@ -3927,7 +3927,8 @@ fn needsPointerRebase(ty: Type, val: Value) bool {...@@ -3927,7 +3927,8 @@ fn needsPointerRebase(ty: Type, val: Value) bool {
39273927
3928fn getMatchingSectionAtom(self: *MachO, atom: *Atom, name: []const u8, ty: Type, val: Value) !MatchingSection {3928fn getMatchingSectionAtom(self: *MachO, atom: *Atom, name: []const u8, ty: Type, val: Value) !MatchingSection {
3929 const code = atom.code.items;3929 const code = atom.code.items;
3930 const alignment = ty.abiAlignment(self.base.options.target);3930 const target = self.base.options.target;
3931 const alignment = ty.abiAlignment(target);
3931 const align_log_2 = math.log2(alignment);3932 const align_log_2 = math.log2(alignment);
3932 const zig_ty = ty.zigTypeTag();3933 const zig_ty = ty.zigTypeTag();
3933 const mode = self.base.options.optimize_mode;3934 const mode = self.base.options.optimize_mode;
...@@ -3954,7 +3955,7 @@ fn getMatchingSectionAtom(self: *MachO, atom: *Atom, name: []const u8, ty: Type,...@@ -3954,7 +3955,7 @@ fn getMatchingSectionAtom(self: *MachO, atom: *Atom, name: []const u8, ty: Type,
3954 };3955 };
3955 }3956 }
39563957
3957 if (needsPointerRebase(ty, val)) {3958 if (needsPointerRebase(ty, val, target)) {
3958 break :blk (try self.getMatchingSection(.{3959 break :blk (try self.getMatchingSection(.{
3959 .segname = makeStaticString("__DATA_CONST"),3960 .segname = makeStaticString("__DATA_CONST"),
3960 .sectname = makeStaticString("__const"),3961 .sectname = makeStaticString("__const"),
src/print_air.zig+6-6
...@@ -299,12 +299,12 @@ const Writer = struct {...@@ -299,12 +299,12 @@ const Writer = struct {
299299
300 fn writeTy(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {300 fn writeTy(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
301 const ty = w.air.instructions.items(.data)[inst].ty;301 const ty = w.air.instructions.items(.data)[inst].ty;
302 try s.print("{}", .{ty});302 try s.print("{}", .{ty.fmtDebug()});
303 }303 }
304304
305 fn writeTyOp(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {305 fn writeTyOp(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
306 const ty_op = w.air.instructions.items(.data)[inst].ty_op;306 const ty_op = w.air.instructions.items(.data)[inst].ty_op;
307 try s.print("{}, ", .{w.air.getRefType(ty_op.ty)});307 try s.print("{}, ", .{w.air.getRefType(ty_op.ty).fmtDebug()});
308 try w.writeOperand(s, inst, 0, ty_op.operand);308 try w.writeOperand(s, inst, 0, ty_op.operand);
309 }309 }
310310
...@@ -313,7 +313,7 @@ const Writer = struct {...@@ -313,7 +313,7 @@ const Writer = struct {
313 const extra = w.air.extraData(Air.Block, ty_pl.payload);313 const extra = w.air.extraData(Air.Block, ty_pl.payload);
314 const body = w.air.extra[extra.end..][0..extra.data.body_len];314 const body = w.air.extra[extra.end..][0..extra.data.body_len];
315315
316 try s.print("{}, {{\n", .{w.air.getRefType(ty_pl.ty)});316 try s.print("{}, {{\n", .{w.air.getRefType(ty_pl.ty).fmtDebug()});
317 const old_indent = w.indent;317 const old_indent = w.indent;
318 w.indent += 2;318 w.indent += 2;
319 try w.writeBody(s, body);319 try w.writeBody(s, body);
...@@ -328,7 +328,7 @@ const Writer = struct {...@@ -328,7 +328,7 @@ const Writer = struct {
328 const len = @intCast(usize, vector_ty.arrayLen());328 const len = @intCast(usize, vector_ty.arrayLen());
329 const elements = @bitCast([]const Air.Inst.Ref, w.air.extra[ty_pl.payload..][0..len]);329 const elements = @bitCast([]const Air.Inst.Ref, w.air.extra[ty_pl.payload..][0..len]);
330330
331 try s.print("{}, [", .{vector_ty});331 try s.print("{}, [", .{vector_ty.fmtDebug()});
332 for (elements) |elem, i| {332 for (elements) |elem, i| {
333 if (i != 0) try s.writeAll(", ");333 if (i != 0) try s.writeAll(", ");
334 try w.writeOperand(s, inst, i, elem);334 try w.writeOperand(s, inst, i, elem);
...@@ -502,7 +502,7 @@ const Writer = struct {...@@ -502,7 +502,7 @@ const Writer = struct {
502 fn writeConstant(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {502 fn writeConstant(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
503 const ty_pl = w.air.instructions.items(.data)[inst].ty_pl;503 const ty_pl = w.air.instructions.items(.data)[inst].ty_pl;
504 const val = w.air.values[ty_pl.payload];504 const val = w.air.values[ty_pl.payload];
505 try s.print("{}, {}", .{ w.air.getRefType(ty_pl.ty), val.fmtDebug() });505 try s.print("{}, {}", .{ w.air.getRefType(ty_pl.ty).fmtDebug(), val.fmtDebug() });
506 }506 }
507507
508 fn writeAssembly(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {508 fn writeAssembly(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
...@@ -514,7 +514,7 @@ const Writer = struct {...@@ -514,7 +514,7 @@ const Writer = struct {
514 var op_index: usize = 0;514 var op_index: usize = 0;
515515
516 const ret_ty = w.air.typeOfIndex(inst);516 const ret_ty = w.air.typeOfIndex(inst);
517 try s.print("{}", .{ret_ty});517 try s.print("{}", .{ret_ty.fmtDebug()});
518518
519 if (is_volatile) {519 if (is_volatile) {
520 try s.writeAll(", volatile");520 try s.writeAll(", volatile");
src/type.zig+488-248
...@@ -6,6 +6,7 @@ const Target = std.Target;...@@ -6,6 +6,7 @@ const Target = std.Target;
6const Module = @import("Module.zig");6const Module = @import("Module.zig");
7const log = std.log.scoped(.Type);7const log = std.log.scoped(.Type);
8const target_util = @import("target.zig");8const target_util = @import("target.zig");
9const TypedValue = @import("TypedValue.zig");
910
10const file_struct = @This();11const file_struct = @This();
1112
...@@ -520,7 +521,7 @@ pub const Type = extern union {...@@ -520,7 +521,7 @@ pub const Type = extern union {
520 }521 }
521 }522 }
522523
523 pub fn eql(a: Type, b: Type) bool {524 pub fn eql(a: Type, b: Type, target: Target) bool {
524 // As a shortcut, if the small tags / addresses match, we're done.525 // As a shortcut, if the small tags / addresses match, we're done.
525 if (a.tag_if_small_enough == b.tag_if_small_enough) return true;526 if (a.tag_if_small_enough == b.tag_if_small_enough) return true;
526527
...@@ -636,7 +637,7 @@ pub const Type = extern union {...@@ -636,7 +637,7 @@ pub const Type = extern union {
636 const a_info = a.fnInfo();637 const a_info = a.fnInfo();
637 const b_info = b.fnInfo();638 const b_info = b.fnInfo();
638639
639 if (!eql(a_info.return_type, b_info.return_type))640 if (!eql(a_info.return_type, b_info.return_type, target))
640 return false;641 return false;
641642
642 if (a_info.cc != b_info.cc)643 if (a_info.cc != b_info.cc)
...@@ -662,7 +663,7 @@ pub const Type = extern union {...@@ -662,7 +663,7 @@ pub const Type = extern union {
662 if (a_param_ty.tag() == .generic_poison) continue;663 if (a_param_ty.tag() == .generic_poison) continue;
663 if (b_param_ty.tag() == .generic_poison) continue;664 if (b_param_ty.tag() == .generic_poison) continue;
664665
665 if (!eql(a_param_ty, b_param_ty))666 if (!eql(a_param_ty, b_param_ty, target))
666 return false;667 return false;
667 }668 }
668669
...@@ -680,13 +681,13 @@ pub const Type = extern union {...@@ -680,13 +681,13 @@ pub const Type = extern union {
680 if (a.arrayLen() != b.arrayLen())681 if (a.arrayLen() != b.arrayLen())
681 return false;682 return false;
682 const elem_ty = a.elemType();683 const elem_ty = a.elemType();
683 if (!elem_ty.eql(b.elemType()))684 if (!elem_ty.eql(b.elemType(), target))
684 return false;685 return false;
685 const sentinel_a = a.sentinel();686 const sentinel_a = a.sentinel();
686 const sentinel_b = b.sentinel();687 const sentinel_b = b.sentinel();
687 if (sentinel_a) |sa| {688 if (sentinel_a) |sa| {
688 if (sentinel_b) |sb| {689 if (sentinel_b) |sb| {
689 return sa.eql(sb, elem_ty);690 return sa.eql(sb, elem_ty, target);
690 } else {691 } else {
691 return false;692 return false;
692 }693 }
...@@ -717,7 +718,7 @@ pub const Type = extern union {...@@ -717,7 +718,7 @@ pub const Type = extern union {
717718
718 const info_a = a.ptrInfo().data;719 const info_a = a.ptrInfo().data;
719 const info_b = b.ptrInfo().data;720 const info_b = b.ptrInfo().data;
720 if (!info_a.pointee_type.eql(info_b.pointee_type))721 if (!info_a.pointee_type.eql(info_b.pointee_type, target))
721 return false;722 return false;
722 if (info_a.@"align" != info_b.@"align")723 if (info_a.@"align" != info_b.@"align")
723 return false;724 return false;
...@@ -740,7 +741,7 @@ pub const Type = extern union {...@@ -740,7 +741,7 @@ pub const Type = extern union {
740 const sentinel_b = info_b.sentinel;741 const sentinel_b = info_b.sentinel;
741 if (sentinel_a) |sa| {742 if (sentinel_a) |sa| {
742 if (sentinel_b) |sb| {743 if (sentinel_b) |sb| {
743 if (!sa.eql(sb, info_a.pointee_type))744 if (!sa.eql(sb, info_a.pointee_type, target))
744 return false;745 return false;
745 } else {746 } else {
746 return false;747 return false;
...@@ -761,7 +762,7 @@ pub const Type = extern union {...@@ -761,7 +762,7 @@ pub const Type = extern union {
761762
762 var buf_a: Payload.ElemType = undefined;763 var buf_a: Payload.ElemType = undefined;
763 var buf_b: Payload.ElemType = undefined;764 var buf_b: Payload.ElemType = undefined;
764 return a.optionalChild(&buf_a).eql(b.optionalChild(&buf_b));765 return a.optionalChild(&buf_a).eql(b.optionalChild(&buf_b), target);
765 },766 },
766767
767 .anyerror_void_error_union, .error_union => {768 .anyerror_void_error_union, .error_union => {
...@@ -769,18 +770,18 @@ pub const Type = extern union {...@@ -769,18 +770,18 @@ pub const Type = extern union {
769770
770 const a_set = a.errorUnionSet();771 const a_set = a.errorUnionSet();
771 const b_set = b.errorUnionSet();772 const b_set = b.errorUnionSet();
772 if (!a_set.eql(b_set)) return false;773 if (!a_set.eql(b_set, target)) return false;
773774
774 const a_payload = a.errorUnionPayload();775 const a_payload = a.errorUnionPayload();
775 const b_payload = b.errorUnionPayload();776 const b_payload = b.errorUnionPayload();
776 if (!a_payload.eql(b_payload)) return false;777 if (!a_payload.eql(b_payload, target)) return false;
777778
778 return true;779 return true;
779 },780 },
780781
781 .anyframe_T => {782 .anyframe_T => {
782 if (b.zigTypeTag() != .AnyFrame) return false;783 if (b.zigTypeTag() != .AnyFrame) return false;
783 return a.childType().eql(b.childType());784 return a.childType().eql(b.childType(), target);
784 },785 },
785786
786 .empty_struct => {787 .empty_struct => {
...@@ -803,7 +804,7 @@ pub const Type = extern union {...@@ -803,7 +804,7 @@ pub const Type = extern union {
803804
804 for (a_tuple.types) |a_ty, i| {805 for (a_tuple.types) |a_ty, i| {
805 const b_ty = b_tuple.types[i];806 const b_ty = b_tuple.types[i];
806 if (!eql(a_ty, b_ty)) return false;807 if (!eql(a_ty, b_ty, target)) return false;
807 }808 }
808809
809 for (a_tuple.values) |a_val, i| {810 for (a_tuple.values) |a_val, i| {
...@@ -819,7 +820,7 @@ pub const Type = extern union {...@@ -819,7 +820,7 @@ pub const Type = extern union {
819 if (b_val.tag() == .unreachable_value) {820 if (b_val.tag() == .unreachable_value) {
820 return false;821 return false;
821 } else {822 } else {
822 if (!Value.eql(a_val, b_val, ty)) return false;823 if (!Value.eql(a_val, b_val, ty, target)) return false;
823 }824 }
824 }825 }
825 }826 }
...@@ -839,7 +840,7 @@ pub const Type = extern union {...@@ -839,7 +840,7 @@ pub const Type = extern union {
839840
840 for (a_struct_obj.types) |a_ty, i| {841 for (a_struct_obj.types) |a_ty, i| {
841 const b_ty = b_struct_obj.types[i];842 const b_ty = b_struct_obj.types[i];
842 if (!eql(a_ty, b_ty)) return false;843 if (!eql(a_ty, b_ty, target)) return false;
843 }844 }
844845
845 for (a_struct_obj.values) |a_val, i| {846 for (a_struct_obj.values) |a_val, i| {
...@@ -855,7 +856,7 @@ pub const Type = extern union {...@@ -855,7 +856,7 @@ pub const Type = extern union {
855 if (b_val.tag() == .unreachable_value) {856 if (b_val.tag() == .unreachable_value) {
856 return false;857 return false;
857 } else {858 } else {
858 if (!Value.eql(a_val, b_val, ty)) return false;859 if (!Value.eql(a_val, b_val, ty, target)) return false;
859 }860 }
860 }861 }
861 }862 }
...@@ -910,13 +911,13 @@ pub const Type = extern union {...@@ -910,13 +911,13 @@ pub const Type = extern union {
910 }911 }
911 }912 }
912913
913 pub fn hash(self: Type) u64 {914 pub fn hash(self: Type, target: Target) u64 {
914 var hasher = std.hash.Wyhash.init(0);915 var hasher = std.hash.Wyhash.init(0);
915 self.hashWithHasher(&hasher);916 self.hashWithHasher(&hasher, target);
916 return hasher.final();917 return hasher.final();
917 }918 }
918919
919 pub fn hashWithHasher(ty: Type, hasher: *std.hash.Wyhash) void {920 pub fn hashWithHasher(ty: Type, hasher: *std.hash.Wyhash, target: Target) void {
920 switch (ty.tag()) {921 switch (ty.tag()) {
921 .generic_poison => unreachable,922 .generic_poison => unreachable,
922923
...@@ -1035,7 +1036,7 @@ pub const Type = extern union {...@@ -1035,7 +1036,7 @@ pub const Type = extern union {
1035 std.hash.autoHash(hasher, std.builtin.TypeId.Fn);1036 std.hash.autoHash(hasher, std.builtin.TypeId.Fn);
10361037
1037 const fn_info = ty.fnInfo();1038 const fn_info = ty.fnInfo();
1038 hashWithHasher(fn_info.return_type, hasher);1039 hashWithHasher(fn_info.return_type, hasher, target);
1039 std.hash.autoHash(hasher, fn_info.alignment);1040 std.hash.autoHash(hasher, fn_info.alignment);
1040 std.hash.autoHash(hasher, fn_info.cc);1041 std.hash.autoHash(hasher, fn_info.cc);
1041 std.hash.autoHash(hasher, fn_info.is_var_args);1042 std.hash.autoHash(hasher, fn_info.is_var_args);
...@@ -1045,7 +1046,7 @@ pub const Type = extern union {...@@ -1045,7 +1046,7 @@ pub const Type = extern union {
1045 for (fn_info.param_types) |param_ty, i| {1046 for (fn_info.param_types) |param_ty, i| {
1046 std.hash.autoHash(hasher, fn_info.paramIsComptime(i));1047 std.hash.autoHash(hasher, fn_info.paramIsComptime(i));
1047 if (param_ty.tag() == .generic_poison) continue;1048 if (param_ty.tag() == .generic_poison) continue;
1048 hashWithHasher(param_ty, hasher);1049 hashWithHasher(param_ty, hasher, target);
1049 }1050 }
1050 },1051 },
10511052
...@@ -1058,8 +1059,8 @@ pub const Type = extern union {...@@ -1058,8 +1059,8 @@ pub const Type = extern union {
10581059
1059 const elem_ty = ty.elemType();1060 const elem_ty = ty.elemType();
1060 std.hash.autoHash(hasher, ty.arrayLen());1061 std.hash.autoHash(hasher, ty.arrayLen());
1061 hashWithHasher(elem_ty, hasher);1062 hashWithHasher(elem_ty, hasher, target);
1062 hashSentinel(ty.sentinel(), elem_ty, hasher);1063 hashSentinel(ty.sentinel(), elem_ty, hasher, target);
1063 },1064 },
10641065
1065 .vector => {1066 .vector => {
...@@ -1067,7 +1068,7 @@ pub const Type = extern union {...@@ -1067,7 +1068,7 @@ pub const Type = extern union {
10671068
1068 const elem_ty = ty.elemType();1069 const elem_ty = ty.elemType();
1069 std.hash.autoHash(hasher, ty.vectorLen());1070 std.hash.autoHash(hasher, ty.vectorLen());
1070 hashWithHasher(elem_ty, hasher);1071 hashWithHasher(elem_ty, hasher, target);
1071 },1072 },
10721073
1073 .single_const_pointer_to_comptime_int,1074 .single_const_pointer_to_comptime_int,
...@@ -1091,8 +1092,8 @@ pub const Type = extern union {...@@ -1091,8 +1092,8 @@ pub const Type = extern union {
1091 std.hash.autoHash(hasher, std.builtin.TypeId.Pointer);1092 std.hash.autoHash(hasher, std.builtin.TypeId.Pointer);
10921093
1093 const info = ty.ptrInfo().data;1094 const info = ty.ptrInfo().data;
1094 hashWithHasher(info.pointee_type, hasher);1095 hashWithHasher(info.pointee_type, hasher, target);
1095 hashSentinel(info.sentinel, info.pointee_type, hasher);1096 hashSentinel(info.sentinel, info.pointee_type, hasher, target);
1096 std.hash.autoHash(hasher, info.@"align");1097 std.hash.autoHash(hasher, info.@"align");
1097 std.hash.autoHash(hasher, info.@"addrspace");1098 std.hash.autoHash(hasher, info.@"addrspace");
1098 std.hash.autoHash(hasher, info.bit_offset);1099 std.hash.autoHash(hasher, info.bit_offset);
...@@ -1110,22 +1111,22 @@ pub const Type = extern union {...@@ -1110,22 +1111,22 @@ pub const Type = extern union {
1110 std.hash.autoHash(hasher, std.builtin.TypeId.Optional);1111 std.hash.autoHash(hasher, std.builtin.TypeId.Optional);
11111112
1112 var buf: Payload.ElemType = undefined;1113 var buf: Payload.ElemType = undefined;
1113 hashWithHasher(ty.optionalChild(&buf), hasher);1114 hashWithHasher(ty.optionalChild(&buf), hasher, target);
1114 },1115 },
11151116
1116 .anyerror_void_error_union, .error_union => {1117 .anyerror_void_error_union, .error_union => {
1117 std.hash.autoHash(hasher, std.builtin.TypeId.ErrorUnion);1118 std.hash.autoHash(hasher, std.builtin.TypeId.ErrorUnion);
11181119
1119 const set_ty = ty.errorUnionSet();1120 const set_ty = ty.errorUnionSet();
1120 hashWithHasher(set_ty, hasher);1121 hashWithHasher(set_ty, hasher, target);
11211122
1122 const payload_ty = ty.errorUnionPayload();1123 const payload_ty = ty.errorUnionPayload();
1123 hashWithHasher(payload_ty, hasher);1124 hashWithHasher(payload_ty, hasher, target);
1124 },1125 },
11251126
1126 .anyframe_T => {1127 .anyframe_T => {
1127 std.hash.autoHash(hasher, std.builtin.TypeId.AnyFrame);1128 std.hash.autoHash(hasher, std.builtin.TypeId.AnyFrame);
1128 hashWithHasher(ty.childType(), hasher);1129 hashWithHasher(ty.childType(), hasher, target);
1129 },1130 },
11301131
1131 .empty_struct => {1132 .empty_struct => {
...@@ -1144,10 +1145,10 @@ pub const Type = extern union {...@@ -1144,10 +1145,10 @@ pub const Type = extern union {
1144 std.hash.autoHash(hasher, tuple.types.len);1145 std.hash.autoHash(hasher, tuple.types.len);
11451146
1146 for (tuple.types) |field_ty, i| {1147 for (tuple.types) |field_ty, i| {
1147 hashWithHasher(field_ty, hasher);1148 hashWithHasher(field_ty, hasher, target);
1148 const field_val = tuple.values[i];1149 const field_val = tuple.values[i];
1149 if (field_val.tag() == .unreachable_value) continue;1150 if (field_val.tag() == .unreachable_value) continue;
1150 field_val.hash(field_ty, hasher);1151 field_val.hash(field_ty, hasher, target);
1151 }1152 }
1152 },1153 },
1153 .anon_struct => {1154 .anon_struct => {
...@@ -1159,9 +1160,9 @@ pub const Type = extern union {...@@ -1159,9 +1160,9 @@ pub const Type = extern union {
1159 const field_name = struct_obj.names[i];1160 const field_name = struct_obj.names[i];
1160 const field_val = struct_obj.values[i];1161 const field_val = struct_obj.values[i];
1161 hasher.update(field_name);1162 hasher.update(field_name);
1162 hashWithHasher(field_ty, hasher);1163 hashWithHasher(field_ty, hasher, target);
1163 if (field_val.tag() == .unreachable_value) continue;1164 if (field_val.tag() == .unreachable_value) continue;
1164 field_val.hash(field_ty, hasher);1165 field_val.hash(field_ty, hasher, target);
1165 }1166 }
1166 },1167 },
11671168
...@@ -1209,35 +1210,35 @@ pub const Type = extern union {...@@ -1209,35 +1210,35 @@ pub const Type = extern union {
1209 }1210 }
1210 }1211 }
12111212
1212 fn hashSentinel(opt_val: ?Value, ty: Type, hasher: *std.hash.Wyhash) void {1213 fn hashSentinel(opt_val: ?Value, ty: Type, hasher: *std.hash.Wyhash, target: Target) void {
1213 if (opt_val) |s| {1214 if (opt_val) |s| {
1214 std.hash.autoHash(hasher, true);1215 std.hash.autoHash(hasher, true);
1215 s.hash(ty, hasher);1216 s.hash(ty, hasher, target);
1216 } else {1217 } else {
1217 std.hash.autoHash(hasher, false);1218 std.hash.autoHash(hasher, false);
1218 }1219 }
1219 }1220 }
12201221
1221 pub const HashContext64 = struct {1222 pub const HashContext64 = struct {
1223 target: Target,
1224
1222 pub fn hash(self: @This(), t: Type) u64 {1225 pub fn hash(self: @This(), t: Type) u64 {
1223 _ = self;1226 return t.hash(self.target);
1224 return t.hash();
1225 }1227 }
1226 pub fn eql(self: @This(), a: Type, b: Type) bool {1228 pub fn eql(self: @This(), a: Type, b: Type) bool {
1227 _ = self;1229 return a.eql(b, self.target);
1228 return a.eql(b);
1229 }1230 }
1230 };1231 };
12311232
1232 pub const HashContext32 = struct {1233 pub const HashContext32 = struct {
1234 target: Target,
1235
1233 pub fn hash(self: @This(), t: Type) u32 {1236 pub fn hash(self: @This(), t: Type) u32 {
1234 _ = self;1237 return @truncate(u32, t.hash(self.target));
1235 return @truncate(u32, t.hash());
1236 }1238 }
1237 pub fn eql(self: @This(), a: Type, b: Type, b_index: usize) bool {1239 pub fn eql(self: @This(), a: Type, b: Type, b_index: usize) bool {
1238 _ = self;
1239 _ = b_index;1240 _ = b_index;
1240 return a.eql(b);1241 return a.eql(b, self.target);
1241 }1242 }
1242 };1243 };
12431244
...@@ -1404,8 +1405,8 @@ pub const Type = extern union {...@@ -1404,8 +1405,8 @@ pub const Type = extern union {
1404 .function => {1405 .function => {
1405 const payload = self.castTag(.function).?.data;1406 const payload = self.castTag(.function).?.data;
1406 const param_types = try allocator.alloc(Type, payload.param_types.len);1407 const param_types = try allocator.alloc(Type, payload.param_types.len);
1407 for (payload.param_types) |param_type, i| {1408 for (payload.param_types) |param_ty, i| {
1408 param_types[i] = try param_type.copy(allocator);1409 param_types[i] = try param_ty.copy(allocator);
1409 }1410 }
1410 const other_comptime_params = payload.comptime_params[0..payload.param_types.len];1411 const other_comptime_params = payload.comptime_params[0..payload.param_types.len];
1411 const comptime_params = try allocator.dupe(bool, other_comptime_params);1412 const comptime_params = try allocator.dupe(bool, other_comptime_params);
...@@ -1474,14 +1475,42 @@ pub const Type = extern union {...@@ -1474,14 +1475,42 @@ pub const Type = extern union {
1474 return Type{ .ptr_otherwise = &new_payload.base };1475 return Type{ .ptr_otherwise = &new_payload.base };
1475 }1476 }
14761477
1477 pub fn format(1478 pub fn format(ty: Type, comptime unused_fmt_string: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
1479 _ = ty;
1480 _ = unused_fmt_string;
1481 _ = options;
1482 _ = writer;
1483 @compileError("do not format types directly; use either ty.fmtDebug() or ty.fmt()");
1484 }
1485
1486 pub fn fmt(ty: Type, target: Target) std.fmt.Formatter(TypedValue.format) {
1487 var ty_payload: Value.Payload.Ty = .{
1488 .base = .{ .tag = .ty },
1489 .data = ty,
1490 };
1491 return .{ .data = .{
1492 .tv = .{
1493 .ty = Type.type,
1494 .val = Value.initPayload(&ty_payload.base),
1495 },
1496 .target = target,
1497 } };
1498 }
1499
1500 pub fn fmtDebug(ty: Type) std.fmt.Formatter(dump) {
1501 return .{ .data = ty };
1502 }
1503
1504 /// This is a debug function. In order to print types in a meaningful way
1505 /// we also need access to the target.
1506 pub fn dump(
1478 start_type: Type,1507 start_type: Type,
1479 comptime fmt: []const u8,1508 comptime unused_format_string: []const u8,
1480 options: std.fmt.FormatOptions,1509 options: std.fmt.FormatOptions,
1481 writer: anytype,1510 writer: anytype,
1482 ) @TypeOf(writer).Error!void {1511 ) @TypeOf(writer).Error!void {
1483 _ = options;1512 _ = options;
1484 comptime assert(fmt.len == 0);1513 comptime assert(unused_format_string.len == 0);
1485 var ty = start_type;1514 var ty = start_type;
1486 while (true) {1515 while (true) {
1487 const t = ty.tag();1516 const t = ty.tag();
...@@ -1584,7 +1613,7 @@ pub const Type = extern union {...@@ -1584,7 +1613,7 @@ pub const Type = extern union {
1584 try writer.writeAll("fn(");1613 try writer.writeAll("fn(");
1585 for (payload.param_types) |param_type, i| {1614 for (payload.param_types) |param_type, i| {
1586 if (i != 0) try writer.writeAll(", ");1615 if (i != 0) try writer.writeAll(", ");
1587 try param_type.format("", .{}, writer);1616 try param_type.dump("", .{}, writer);
1588 }1617 }
1589 if (payload.is_var_args) {1618 if (payload.is_var_args) {
1590 if (payload.param_types.len != 0) {1619 if (payload.param_types.len != 0) {
...@@ -1622,7 +1651,7 @@ pub const Type = extern union {...@@ -1622,7 +1651,7 @@ pub const Type = extern union {
1622 .vector => {1651 .vector => {
1623 const payload = ty.castTag(.vector).?.data;1652 const payload = ty.castTag(.vector).?.data;
1624 try writer.print("@Vector({d}, ", .{payload.len});1653 try writer.print("@Vector({d}, ", .{payload.len});
1625 try payload.elem_type.format("", .{}, writer);1654 try payload.elem_type.dump("", .{}, writer);
1626 return writer.writeAll(")");1655 return writer.writeAll(")");
1627 },1656 },
1628 .array => {1657 .array => {
...@@ -1633,7 +1662,10 @@ pub const Type = extern union {...@@ -1633,7 +1662,10 @@ pub const Type = extern union {
1633 },1662 },
1634 .array_sentinel => {1663 .array_sentinel => {
1635 const payload = ty.castTag(.array_sentinel).?.data;1664 const payload = ty.castTag(.array_sentinel).?.data;
1636 try writer.print("[{d}:{}]", .{ payload.len, payload.sentinel.fmtValue(payload.elem_type) });1665 try writer.print("[{d}:{}]", .{
1666 payload.len,
1667 payload.sentinel.fmtDebug(),
1668 });
1637 ty = payload.elem_type;1669 ty = payload.elem_type;
1638 continue;1670 continue;
1639 },1671 },
...@@ -1646,9 +1678,9 @@ pub const Type = extern union {...@@ -1646,9 +1678,9 @@ pub const Type = extern union {
1646 if (val.tag() != .unreachable_value) {1678 if (val.tag() != .unreachable_value) {
1647 try writer.writeAll("comptime ");1679 try writer.writeAll("comptime ");
1648 }1680 }
1649 try field_ty.format("", .{}, writer);1681 try field_ty.dump("", .{}, writer);
1650 if (val.tag() != .unreachable_value) {1682 if (val.tag() != .unreachable_value) {
1651 try writer.print(" = {}", .{val.fmtValue(field_ty)});1683 try writer.print(" = {}", .{val.fmtDebug()});
1652 }1684 }
1653 }1685 }
1654 try writer.writeAll("}");1686 try writer.writeAll("}");
...@@ -1665,9 +1697,9 @@ pub const Type = extern union {...@@ -1665,9 +1697,9 @@ pub const Type = extern union {
1665 }1697 }
1666 try writer.writeAll(anon_struct.names[i]);1698 try writer.writeAll(anon_struct.names[i]);
1667 try writer.writeAll(": ");1699 try writer.writeAll(": ");
1668 try field_ty.format("", .{}, writer);1700 try field_ty.dump("", .{}, writer);
1669 if (val.tag() != .unreachable_value) {1701 if (val.tag() != .unreachable_value) {
1670 try writer.print(" = {}", .{val.fmtValue(field_ty)});1702 try writer.print(" = {}", .{val.fmtDebug()});
1671 }1703 }
1672 }1704 }
1673 try writer.writeAll("}");1705 try writer.writeAll("}");
...@@ -1752,8 +1784,8 @@ pub const Type = extern union {...@@ -1752,8 +1784,8 @@ pub const Type = extern union {
1752 const payload = ty.castTag(.pointer).?.data;1784 const payload = ty.castTag(.pointer).?.data;
1753 if (payload.sentinel) |some| switch (payload.size) {1785 if (payload.sentinel) |some| switch (payload.size) {
1754 .One, .C => unreachable,1786 .One, .C => unreachable,
1755 .Many => try writer.print("[*:{}]", .{some.fmtValue(payload.pointee_type)}),1787 .Many => try writer.print("[*:{}]", .{some.fmtDebug()}),
1756 .Slice => try writer.print("[:{}]", .{some.fmtValue(payload.pointee_type)}),1788 .Slice => try writer.print("[:{}]", .{some.fmtDebug()}),
1757 } else switch (payload.size) {1789 } else switch (payload.size) {
1758 .One => try writer.writeAll("*"),1790 .One => try writer.writeAll("*"),
1759 .Many => try writer.writeAll("[*]"),1791 .Many => try writer.writeAll("[*]"),
...@@ -1780,7 +1812,7 @@ pub const Type = extern union {...@@ -1780,7 +1812,7 @@ pub const Type = extern union {
1780 },1812 },
1781 .error_union => {1813 .error_union => {
1782 const payload = ty.castTag(.error_union).?.data;1814 const payload = ty.castTag(.error_union).?.data;
1783 try payload.error_set.format("", .{}, writer);1815 try payload.error_set.dump("", .{}, writer);
1784 try writer.writeAll("!");1816 try writer.writeAll("!");
1785 ty = payload.payload;1817 ty = payload.payload;
1786 continue;1818 continue;
...@@ -1821,20 +1853,17 @@ pub const Type = extern union {...@@ -1821,20 +1853,17 @@ pub const Type = extern union {
1821 }1853 }
1822 }1854 }
18231855
1824 pub fn nameAllocArena(ty: Type, arena: Allocator) Allocator.Error![:0]const u8 {1856 pub const nameAllocArena = nameAlloc;
1825 return nameAllocAdvanced(ty, arena, true);
1826 }
18271857
1828 pub fn nameAlloc(ty: Type, gpa: Allocator) Allocator.Error![:0]const u8 {1858 pub fn nameAlloc(ty: Type, ally: Allocator, target: Target) Allocator.Error![:0]const u8 {
1829 return nameAllocAdvanced(ty, gpa, false);1859 var buffer = std.ArrayList(u8).init(ally);
1860 defer buffer.deinit();
1861 try ty.print(buffer.writer(), target);
1862 return buffer.toOwnedSliceSentinel(0);
1830 }1863 }
18311864
1832 /// Returns a name suitable for `@typeName`.1865 /// Prints a name suitable for `@typeName`.
1833 pub fn nameAllocAdvanced(1866 pub fn print(ty: Type, writer: anytype, target: Target) @TypeOf(writer).Error!void {
1834 ty: Type,
1835 ally: Allocator,
1836 is_arena: bool,
1837 ) Allocator.Error![:0]const u8 {
1838 const t = ty.tag();1867 const t = ty.tag();
1839 switch (t) {1868 switch (t) {
1840 .inferred_alloc_const => unreachable,1869 .inferred_alloc_const => unreachable,
...@@ -1892,141 +1921,251 @@ pub const Type = extern union {...@@ -1892,141 +1921,251 @@ pub const Type = extern union {
1892 .comptime_int,1921 .comptime_int,
1893 .comptime_float,1922 .comptime_float,
1894 .noreturn,1923 .noreturn,
1895 => return maybeDupe(@tagName(t), ally, is_arena),1924 => try writer.writeAll(@tagName(t)),
18961925
1897 .enum_literal => return maybeDupe("@TypeOf(.enum_literal)", ally, is_arena),1926 .enum_literal => try writer.writeAll("@TypeOf(.enum_literal)"),
1898 .@"null" => return maybeDupe("@TypeOf(null)", ally, is_arena),1927 .@"null" => try writer.writeAll("@TypeOf(null)"),
1899 .@"undefined" => return maybeDupe("@TypeOf(undefined)", ally, is_arena),1928 .@"undefined" => try writer.writeAll("@TypeOf(undefined)"),
1900 .empty_struct_literal => return maybeDupe("@TypeOf(.{})", ally, is_arena),1929 .empty_struct_literal => try writer.writeAll("@TypeOf(.{})"),
19011930
1902 .empty_struct => {1931 .empty_struct => {
1903 const namespace = ty.castTag(.empty_struct).?.data;1932 const namespace = ty.castTag(.empty_struct).?.data;
1904 var buffer = std.ArrayList(u8).init(ally);1933 try namespace.renderFullyQualifiedName("", writer);
1905 defer buffer.deinit();
1906 try namespace.renderFullyQualifiedName("", buffer.writer());
1907 return buffer.toOwnedSliceSentinel(0);
1908 },1934 },
19091935
1910 .@"struct" => {1936 .@"struct" => {
1911 const struct_obj = ty.castTag(.@"struct").?.data;1937 const struct_obj = ty.castTag(.@"struct").?.data;
1912 return try struct_obj.owner_decl.getFullyQualifiedName(ally);1938 try struct_obj.owner_decl.renderFullyQualifiedName(writer);
1913 },1939 },
1914 .@"union", .union_tagged => {1940 .@"union", .union_tagged => {
1915 const union_obj = ty.cast(Payload.Union).?.data;1941 const union_obj = ty.cast(Payload.Union).?.data;
1916 return try union_obj.owner_decl.getFullyQualifiedName(ally);1942 try union_obj.owner_decl.renderFullyQualifiedName(writer);
1917 },1943 },
1918 .enum_full, .enum_nonexhaustive => {1944 .enum_full, .enum_nonexhaustive => {
1919 const enum_full = ty.cast(Payload.EnumFull).?.data;1945 const enum_full = ty.cast(Payload.EnumFull).?.data;
1920 return try enum_full.owner_decl.getFullyQualifiedName(ally);1946 try enum_full.owner_decl.renderFullyQualifiedName(writer);
1921 },1947 },
1922 .enum_simple => {1948 .enum_simple => {
1923 const enum_simple = ty.castTag(.enum_simple).?.data;1949 const enum_simple = ty.castTag(.enum_simple).?.data;
1924 return try enum_simple.owner_decl.getFullyQualifiedName(ally);1950 try enum_simple.owner_decl.renderFullyQualifiedName(writer);
1925 },1951 },
1926 .enum_numbered => {1952 .enum_numbered => {
1927 const enum_numbered = ty.castTag(.enum_numbered).?.data;1953 const enum_numbered = ty.castTag(.enum_numbered).?.data;
1928 return try enum_numbered.owner_decl.getFullyQualifiedName(ally);1954 try enum_numbered.owner_decl.renderFullyQualifiedName(writer);
1929 },1955 },
1930 .@"opaque" => {1956 .@"opaque" => {
1931 const opaque_obj = ty.cast(Payload.Opaque).?.data;1957 const opaque_obj = ty.cast(Payload.Opaque).?.data;
1932 return try opaque_obj.owner_decl.getFullyQualifiedName(ally);1958 try opaque_obj.owner_decl.renderFullyQualifiedName(writer);
1933 },1959 },
19341960
1935 .anyerror_void_error_union => return maybeDupe("anyerror!void", ally, is_arena),1961 .anyerror_void_error_union => try writer.writeAll("anyerror!void"),
1936 .const_slice_u8 => return maybeDupe("[]const u8", ally, is_arena),1962 .const_slice_u8 => try writer.writeAll("[]const u8"),
1937 .const_slice_u8_sentinel_0 => return maybeDupe("[:0]const u8", ally, is_arena),1963 .const_slice_u8_sentinel_0 => try writer.writeAll("[:0]const u8"),
1938 .fn_noreturn_no_args => return maybeDupe("fn() noreturn", ally, is_arena),1964 .fn_noreturn_no_args => try writer.writeAll("fn() noreturn"),
1939 .fn_void_no_args => return maybeDupe("fn() void", ally, is_arena),1965 .fn_void_no_args => try writer.writeAll("fn() void"),
1940 .fn_naked_noreturn_no_args => return maybeDupe("fn() callconv(.Naked) noreturn", ally, is_arena),1966 .fn_naked_noreturn_no_args => try writer.writeAll("fn() callconv(.Naked) noreturn"),
1941 .fn_ccc_void_no_args => return maybeDupe("fn() callconv(.C) void", ally, is_arena),1967 .fn_ccc_void_no_args => try writer.writeAll("fn() callconv(.C) void"),
1942 .single_const_pointer_to_comptime_int => return maybeDupe("*const comptime_int", ally, is_arena),1968 .single_const_pointer_to_comptime_int => try writer.writeAll("*const comptime_int"),
1943 .manyptr_u8 => return maybeDupe("[*]u8", ally, is_arena),1969 .manyptr_u8 => try writer.writeAll("[*]u8"),
1944 .manyptr_const_u8 => return maybeDupe("[*]const u8", ally, is_arena),1970 .manyptr_const_u8 => try writer.writeAll("[*]const u8"),
1945 .manyptr_const_u8_sentinel_0 => return maybeDupe("[*:0]const u8", ally, is_arena),1971 .manyptr_const_u8_sentinel_0 => try writer.writeAll("[*:0]const u8"),
19461972
1947 .error_set_inferred => {1973 .error_set_inferred => {
1948 const func = ty.castTag(.error_set_inferred).?.data.func;1974 const func = ty.castTag(.error_set_inferred).?.data.func;
19491975
1950 var buf = std.ArrayList(u8).init(ally);1976 try writer.writeAll("@typeInfo(@typeInfo(@TypeOf(");
1951 defer buf.deinit();1977 try func.owner_decl.renderFullyQualifiedName(writer);
1952 try buf.appendSlice("@typeInfo(@typeInfo(@TypeOf(");1978 try writer.writeAll(")).Fn.return_type.?).ErrorUnion.error_set");
1953 try func.owner_decl.renderFullyQualifiedName(buf.writer());
1954 try buf.appendSlice(")).Fn.return_type.?).ErrorUnion.error_set");
1955 return try buf.toOwnedSliceSentinel(0);
1956 },1979 },
19571980
1958 .function => {1981 .function => {
1959 const fn_info = ty.fnInfo();1982 const fn_info = ty.fnInfo();
1960 var buf = std.ArrayList(u8).init(ally);1983 try writer.writeAll("fn(");
1961 defer buf.deinit();1984 for (fn_info.param_types) |param_ty, i| {
1962 try buf.appendSlice("fn(");1985 if (i != 0) try writer.writeAll(", ");
1963 for (fn_info.param_types) |param_type, i| {1986 try print(param_ty, writer, target);
1964 if (i != 0) try buf.appendSlice(", ");
1965 const param_name = try param_type.nameAllocAdvanced(ally, is_arena);
1966 defer if (!is_arena) ally.free(param_name);
1967 try buf.appendSlice(param_name);
1968 }1987 }
1969 if (fn_info.is_var_args) {1988 if (fn_info.is_var_args) {
1970 if (fn_info.param_types.len != 0) {1989 if (fn_info.param_types.len != 0) {
1971 try buf.appendSlice(", ");1990 try writer.writeAll(", ");
1972 }1991 }
1973 try buf.appendSlice("...");1992 try writer.writeAll("...");
1974 }1993 }
1975 try buf.appendSlice(") ");1994 try writer.writeAll(") ");
1976 if (fn_info.cc != .Unspecified) {1995 if (fn_info.cc != .Unspecified) {
1977 try buf.appendSlice("callconv(.");1996 try writer.writeAll("callconv(.");
1978 try buf.appendSlice(@tagName(fn_info.cc));1997 try writer.writeAll(@tagName(fn_info.cc));
1979 try buf.appendSlice(") ");1998 try writer.writeAll(") ");
1980 }1999 }
1981 if (fn_info.alignment != 0) {2000 if (fn_info.alignment != 0) {
1982 try buf.writer().print("align({d}) ", .{fn_info.alignment});2001 try writer.print("align({d}) ", .{fn_info.alignment});
1983 }
1984 {
1985 const ret_ty_name = try fn_info.return_type.nameAllocAdvanced(ally, is_arena);
1986 defer if (!is_arena) ally.free(ret_ty_name);
1987 try buf.appendSlice(ret_ty_name);
1988 }2002 }
1989 return try buf.toOwnedSliceSentinel(0);2003 try print(fn_info.return_type, writer, target);
1990 },2004 },
19912005
1992 .error_union => {2006 .error_union => {
1993 const error_union = ty.castTag(.error_union).?.data;2007 const error_union = ty.castTag(.error_union).?.data;
2008 try print(error_union.error_set, writer, target);
2009 try writer.writeAll("!");
2010 try print(error_union.payload, writer, target);
2011 },
19942012
1995 var buf = std.ArrayList(u8).init(ally);2013 .array_u8 => {
1996 defer buf.deinit();2014 const len = ty.castTag(.array_u8).?.data;
2015 try writer.print("[{d}]u8", .{len});
2016 },
2017 .array_u8_sentinel_0 => {
2018 const len = ty.castTag(.array_u8_sentinel_0).?.data;
2019 try writer.print("[{d}:0]u8", .{len});
2020 },
2021 .vector => {
2022 const payload = ty.castTag(.vector).?.data;
2023 try writer.print("@Vector({d}, ", .{payload.len});
2024 try print(payload.elem_type, writer, target);
2025 try writer.writeAll(")");
2026 },
2027 .array => {
2028 const payload = ty.castTag(.array).?.data;
2029 try writer.print("[{d}]", .{payload.len});
2030 try print(payload.elem_type, writer, target);
2031 },
2032 .array_sentinel => {
2033 const payload = ty.castTag(.array_sentinel).?.data;
2034 try writer.print("[{d}:{}]", .{
2035 payload.len,
2036 payload.sentinel.fmtValue(payload.elem_type, target),
2037 });
2038 try print(payload.elem_type, writer, target);
2039 },
2040 .tuple => {
2041 const tuple = ty.castTag(.tuple).?.data;
19972042
1998 {2043 try writer.writeAll("tuple{");
1999 const err_set_ty_name = try error_union.error_set.nameAllocAdvanced(ally, is_arena);2044 for (tuple.types) |field_ty, i| {
2000 defer if (!is_arena) ally.free(err_set_ty_name);2045 if (i != 0) try writer.writeAll(", ");
2001 try buf.appendSlice(err_set_ty_name);2046 const val = tuple.values[i];
2047 if (val.tag() != .unreachable_value) {
2048 try writer.writeAll("comptime ");
2049 }
2050 try print(field_ty, writer, target);
2051 if (val.tag() != .unreachable_value) {
2052 try writer.print(" = {}", .{val.fmtValue(field_ty, target)});
2053 }
2054 }
2055 try writer.writeAll("}");
2056 },
2057 .anon_struct => {
2058 const anon_struct = ty.castTag(.anon_struct).?.data;
2059
2060 try writer.writeAll("struct{");
2061 for (anon_struct.types) |field_ty, i| {
2062 if (i != 0) try writer.writeAll(", ");
2063 const val = anon_struct.values[i];
2064 if (val.tag() != .unreachable_value) {
2065 try writer.writeAll("comptime ");
2066 }
2067 try writer.writeAll(anon_struct.names[i]);
2068 try writer.writeAll(": ");
2069
2070 try print(field_ty, writer, target);
2071
2072 if (val.tag() != .unreachable_value) {
2073 try writer.print(" = {}", .{val.fmtValue(field_ty, target)});
2074 }
2002 }2075 }
2076 try writer.writeAll("}");
2077 },
20032078
2004 try buf.appendSlice("!");2079 .pointer,
2080 .single_const_pointer,
2081 .single_mut_pointer,
2082 .many_const_pointer,
2083 .many_mut_pointer,
2084 .c_const_pointer,
2085 .c_mut_pointer,
2086 .const_slice,
2087 .mut_slice,
2088 => {
2089 const info = ty.ptrInfo().data;
20052090
2006 {2091 if (info.sentinel) |s| switch (info.size) {
2007 const payload_ty_name = try error_union.payload.nameAllocAdvanced(ally, is_arena);2092 .One, .C => unreachable,
2008 defer if (!is_arena) ally.free(payload_ty_name);2093 .Many => try writer.print("[*:{}]", .{s.fmtValue(info.pointee_type, target)}),
2009 try buf.appendSlice(payload_ty_name);2094 .Slice => try writer.print("[:{}]", .{s.fmtValue(info.pointee_type, target)}),
2095 } else switch (info.size) {
2096 .One => try writer.writeAll("*"),
2097 .Many => try writer.writeAll("[*]"),
2098 .C => try writer.writeAll("[*c]"),
2099 .Slice => try writer.writeAll("[]"),
2010 }2100 }
2101 if (info.@"align" != 0 or info.host_size != 0) {
2102 try writer.print("align({d}", .{info.@"align"});
20112103
2012 return try buf.toOwnedSliceSentinel(0);2104 if (info.bit_offset != 0) {
2013 },2105 try writer.print(":{d}:{d}", .{ info.bit_offset, info.host_size });
2106 }
2107 try writer.writeAll(") ");
2108 }
2109 if (info.@"addrspace" != .generic) {
2110 try writer.print("addrspace(.{s}) ", .{@tagName(info.@"addrspace")});
2111 }
2112 if (!info.mutable) try writer.writeAll("const ");
2113 if (info.@"volatile") try writer.writeAll("volatile ");
2114 if (info.@"allowzero" and info.size != .C) try writer.writeAll("allowzero ");
20142115
2015 else => {2116 try print(info.pointee_type, writer, target);
2016 // TODO this is wasteful and also an incorrect implementation of `@typeName`
2017 var buf = std.ArrayList(u8).init(ally);
2018 defer buf.deinit();
2019 try buf.writer().print("{}", .{ty});
2020 return try buf.toOwnedSliceSentinel(0);
2021 },2117 },
2022 }
2023 }
20242118
2025 fn maybeDupe(s: [:0]const u8, ally: Allocator, is_arena: bool) Allocator.Error![:0]const u8 {2119 .int_signed => {
2026 if (is_arena) {2120 const bits = ty.castTag(.int_signed).?.data;
2027 return s;2121 return writer.print("i{d}", .{bits});
2028 } else {2122 },
2029 return try ally.dupeZ(u8, s);2123 .int_unsigned => {
2124 const bits = ty.castTag(.int_unsigned).?.data;
2125 return writer.print("u{d}", .{bits});
2126 },
2127 .optional => {
2128 const child_type = ty.castTag(.optional).?.data;
2129 try writer.writeByte('?');
2130 try print(child_type, writer, target);
2131 },
2132 .optional_single_mut_pointer => {
2133 const pointee_type = ty.castTag(.optional_single_mut_pointer).?.data;
2134 try writer.writeAll("?*");
2135 try print(pointee_type, writer, target);
2136 },
2137 .optional_single_const_pointer => {
2138 const pointee_type = ty.castTag(.optional_single_const_pointer).?.data;
2139 try writer.writeAll("?*const ");
2140 try print(pointee_type, writer, target);
2141 },
2142 .anyframe_T => {
2143 const return_type = ty.castTag(.anyframe_T).?.data;
2144 try writer.print("anyframe->", .{});
2145 try print(return_type, writer, target);
2146 },
2147 .error_set => {
2148 const names = ty.castTag(.error_set).?.data.names.keys();
2149 try writer.writeAll("error{");
2150 for (names) |name, i| {
2151 if (i != 0) try writer.writeByte(',');
2152 try writer.writeAll(name);
2153 }
2154 try writer.writeAll("}");
2155 },
2156 .error_set_single => {
2157 const name = ty.castTag(.error_set_single).?.data;
2158 return writer.print("error{{{s}}}", .{name});
2159 },
2160 .error_set_merged => {
2161 const names = ty.castTag(.error_set_merged).?.data.keys();
2162 try writer.writeAll("error{");
2163 for (names) |name, i| {
2164 if (i != 0) try writer.writeByte(',');
2165 try writer.writeAll(name);
2166 }
2167 try writer.writeAll("}");
2168 },
2030 }2169 }
2031 }2170 }
20322171
...@@ -2518,8 +2657,33 @@ pub const Type = extern union {...@@ -2518,8 +2657,33 @@ pub const Type = extern union {
2518 }2657 }
25192658
2520 /// Returns 0 for 0-bit types.2659 /// Returns 0 for 0-bit types.
2521 pub fn abiAlignment(self: Type, target: Target) u32 {2660 pub fn abiAlignment(ty: Type, target: Target) u32 {
2522 return switch (self.tag()) {2661 return ty.abiAlignmentAdvanced(target, .eager).scalar;
2662 }
2663
2664 /// May capture a reference to `ty`.
2665 pub fn lazyAbiAlignment(ty: Type, target: Target, arena: Allocator) !Value {
2666 switch (ty.abiAlignmentAdvanced(target, .{ .lazy = arena })) {
2667 .val => |val| return try val,
2668 .scalar => |x| return Value.Tag.int_u64.create(arena, x),
2669 }
2670 }
2671
2672 /// If you pass `eager` you will get back `scalar` and assert the type is resolved.
2673 /// If you pass `lazy` you may get back `scalar` or `val`.
2674 /// If `val` is returned, a reference to `ty` has been captured.
2675 fn abiAlignmentAdvanced(
2676 ty: Type,
2677 target: Target,
2678 strat: union(enum) {
2679 eager,
2680 lazy: Allocator,
2681 },
2682 ) union(enum) {
2683 scalar: u32,
2684 val: Allocator.Error!Value,
2685 } {
2686 return switch (ty.tag()) {
2523 .u1,2687 .u1,
2524 .u8,2688 .u8,
2525 .i8,2689 .i8,
...@@ -2538,25 +2702,25 @@ pub const Type = extern union {...@@ -2538,25 +2702,25 @@ pub const Type = extern union {
2538 .extern_options,2702 .extern_options,
2539 .@"opaque",2703 .@"opaque",
2540 .anyopaque,2704 .anyopaque,
2541 => return 1,2705 => return .{ .scalar = 1 },
25422706
2543 .fn_noreturn_no_args, // represents machine code; not a pointer2707 .fn_noreturn_no_args, // represents machine code; not a pointer
2544 .fn_void_no_args, // represents machine code; not a pointer2708 .fn_void_no_args, // represents machine code; not a pointer
2545 .fn_naked_noreturn_no_args, // represents machine code; not a pointer2709 .fn_naked_noreturn_no_args, // represents machine code; not a pointer
2546 .fn_ccc_void_no_args, // represents machine code; not a pointer2710 .fn_ccc_void_no_args, // represents machine code; not a pointer
2547 => return target_util.defaultFunctionAlignment(target),2711 => return .{ .scalar = target_util.defaultFunctionAlignment(target) },
25482712
2549 // represents machine code; not a pointer2713 // represents machine code; not a pointer
2550 .function => {2714 .function => {
2551 const alignment = self.castTag(.function).?.data.alignment;2715 const alignment = ty.castTag(.function).?.data.alignment;
2552 if (alignment != 0) return alignment;2716 if (alignment != 0) return .{ .scalar = alignment };
2553 return target_util.defaultFunctionAlignment(target);2717 return .{ .scalar = target_util.defaultFunctionAlignment(target) };
2554 },2718 },
25552719
2556 .i16, .u16 => return 2,2720 .i16, .u16 => return .{ .scalar = 2 },
2557 .i32, .u32 => return 4,2721 .i32, .u32 => return .{ .scalar = 4 },
2558 .i64, .u64 => return 8,2722 .i64, .u64 => return .{ .scalar = 8 },
2559 .u128, .i128 => return 16,2723 .u128, .i128 => return .{ .scalar = 16 },
25602724
2561 .isize,2725 .isize,
2562 .usize,2726 .usize,
...@@ -2579,40 +2743,40 @@ pub const Type = extern union {...@@ -2579,40 +2743,40 @@ pub const Type = extern union {
2579 .manyptr_const_u8_sentinel_0,2743 .manyptr_const_u8_sentinel_0,
2580 .@"anyframe",2744 .@"anyframe",
2581 .anyframe_T,2745 .anyframe_T,
2582 => return @divExact(target.cpu.arch.ptrBitWidth(), 8),2746 => return .{ .scalar = @divExact(target.cpu.arch.ptrBitWidth(), 8) },
25832747
2584 .c_short => return @divExact(CType.short.sizeInBits(target), 8),2748 .c_short => return .{ .scalar = @divExact(CType.short.sizeInBits(target), 8) },
2585 .c_ushort => return @divExact(CType.ushort.sizeInBits(target), 8),2749 .c_ushort => return .{ .scalar = @divExact(CType.ushort.sizeInBits(target), 8) },
2586 .c_int => return @divExact(CType.int.sizeInBits(target), 8),2750 .c_int => return .{ .scalar = @divExact(CType.int.sizeInBits(target), 8) },
2587 .c_uint => return @divExact(CType.uint.sizeInBits(target), 8),2751 .c_uint => return .{ .scalar = @divExact(CType.uint.sizeInBits(target), 8) },
2588 .c_long => return @divExact(CType.long.sizeInBits(target), 8),2752 .c_long => return .{ .scalar = @divExact(CType.long.sizeInBits(target), 8) },
2589 .c_ulong => return @divExact(CType.ulong.sizeInBits(target), 8),2753 .c_ulong => return .{ .scalar = @divExact(CType.ulong.sizeInBits(target), 8) },
2590 .c_longlong => return @divExact(CType.longlong.sizeInBits(target), 8),2754 .c_longlong => return .{ .scalar = @divExact(CType.longlong.sizeInBits(target), 8) },
2591 .c_ulonglong => return @divExact(CType.ulonglong.sizeInBits(target), 8),2755 .c_ulonglong => return .{ .scalar = @divExact(CType.ulonglong.sizeInBits(target), 8) },
25922756
2593 .f16 => return 2,2757 .f16 => return .{ .scalar = 2 },
2594 .f32 => return 4,2758 .f32 => return .{ .scalar = 4 },
2595 .f64 => return 8,2759 .f64 => return .{ .scalar = 8 },
2596 .f128 => return 16,2760 .f128 => return .{ .scalar = 16 },
25972761
2598 .f80 => switch (target.cpu.arch) {2762 .f80 => switch (target.cpu.arch) {
2599 .i386 => return 4,2763 .i386 => return .{ .scalar = 4 },
2600 .x86_64 => return 16,2764 .x86_64 => return .{ .scalar = 16 },
2601 else => {2765 else => {
2602 var payload: Payload.Bits = .{2766 var payload: Payload.Bits = .{
2603 .base = .{ .tag = .int_unsigned },2767 .base = .{ .tag = .int_unsigned },
2604 .data = 80,2768 .data = 80,
2605 };2769 };
2606 const u80_ty = initPayload(&payload.base);2770 const u80_ty = initPayload(&payload.base);
2607 return abiAlignment(u80_ty, target);2771 return .{ .scalar = abiAlignment(u80_ty, target) };
2608 },2772 },
2609 },2773 },
2610 .c_longdouble => switch (CType.longdouble.sizeInBits(target)) {2774 .c_longdouble => switch (CType.longdouble.sizeInBits(target)) {
2611 16 => return abiAlignment(Type.f16, target),2775 16 => return .{ .scalar = abiAlignment(Type.f16, target) },
2612 32 => return abiAlignment(Type.f32, target),2776 32 => return .{ .scalar = abiAlignment(Type.f32, target) },
2613 64 => return abiAlignment(Type.f64, target),2777 64 => return .{ .scalar = abiAlignment(Type.f64, target) },
2614 80 => return abiAlignment(Type.f80, target),2778 80 => return .{ .scalar = abiAlignment(Type.f80, target) },
2615 128 => return abiAlignment(Type.f128, target),2779 128 => return .{ .scalar = abiAlignment(Type.f128, target) },
2616 else => unreachable,2780 else => unreachable,
2617 },2781 },
26182782
...@@ -2622,60 +2786,93 @@ pub const Type = extern union {...@@ -2622,60 +2786,93 @@ pub const Type = extern union {
2622 .anyerror,2786 .anyerror,
2623 .error_set_inferred,2787 .error_set_inferred,
2624 .error_set_merged,2788 .error_set_merged,
2625 => return 2, // TODO revisit this when we have the concept of the error tag type2789 => return .{ .scalar = 2 }, // TODO revisit this when we have the concept of the error tag type
26262790
2627 .array, .array_sentinel => return self.elemType().abiAlignment(target),2791 .array, .array_sentinel => return ty.elemType().abiAlignmentAdvanced(target, strat),
26282792
2629 // TODO audit this - is there any more complicated logic to determine2793 // TODO audit this - is there any more complicated logic to determine
2630 // ABI alignment of vectors?2794 // ABI alignment of vectors?
2631 .vector => return 16,2795 .vector => return .{ .scalar = 16 },
26322796
2633 .int_signed, .int_unsigned => {2797 .int_signed, .int_unsigned => {
2634 const bits: u16 = self.cast(Payload.Bits).?.data;2798 const bits: u16 = ty.cast(Payload.Bits).?.data;
2635 if (bits == 0) return 0;2799 if (bits == 0) return .{ .scalar = 0 };
2636 if (bits <= 8) return 1;2800 if (bits <= 8) return .{ .scalar = 1 };
2637 if (bits <= 16) return 2;2801 if (bits <= 16) return .{ .scalar = 2 };
2638 if (bits <= 32) return 4;2802 if (bits <= 32) return .{ .scalar = 4 };
2639 if (bits <= 64) return 8;2803 if (bits <= 64) return .{ .scalar = 8 };
2640 return 16;2804 return .{ .scalar = 16 };
2641 },2805 },
26422806
2643 .optional => {2807 .optional => {
2644 var buf: Payload.ElemType = undefined;2808 var buf: Payload.ElemType = undefined;
2645 const child_type = self.optionalChild(&buf);2809 const child_type = ty.optionalChild(&buf);
2646 if (!child_type.hasRuntimeBits()) return 1;
26472810
2648 if (child_type.zigTypeTag() == .Pointer and !child_type.isCPtr())2811 if (child_type.zigTypeTag() == .Pointer and !child_type.isCPtr()) {
2649 return @divExact(target.cpu.arch.ptrBitWidth(), 8);2812 return .{ .scalar = @divExact(target.cpu.arch.ptrBitWidth(), 8) };
2813 }
26502814
2651 return child_type.abiAlignment(target);2815 switch (strat) {
2816 .eager => {
2817 if (!child_type.hasRuntimeBits()) return .{ .scalar = 1 };
2818 return .{ .scalar = child_type.abiAlignment(target) };
2819 },
2820 .lazy => |arena| switch (child_type.abiAlignmentAdvanced(target, strat)) {
2821 .scalar => |x| return .{ .scalar = @maximum(x, 1) },
2822 .val => return .{ .val = Value.Tag.lazy_align.create(arena, ty) },
2823 },
2824 }
2652 },2825 },
26532826
2654 .error_union => {2827 .error_union => {
2655 const data = self.castTag(.error_union).?.data;2828 const data = ty.castTag(.error_union).?.data;
2656 if (!data.error_set.hasRuntimeBits()) {2829 switch (strat) {
2657 return data.payload.abiAlignment(target);2830 .eager => {
2658 } else if (!data.payload.hasRuntimeBits()) {2831 if (!data.error_set.hasRuntimeBits()) {
2659 return data.error_set.abiAlignment(target);2832 return .{ .scalar = data.payload.abiAlignment(target) };
2833 } else if (!data.payload.hasRuntimeBits()) {
2834 return .{ .scalar = data.error_set.abiAlignment(target) };
2835 }
2836 return .{ .scalar = @maximum(
2837 data.payload.abiAlignment(target),
2838 data.error_set.abiAlignment(target),
2839 ) };
2840 },
2841 .lazy => |arena| {
2842 switch (data.payload.abiAlignmentAdvanced(target, strat)) {
2843 .scalar => |payload_align| {
2844 if (payload_align == 0) {
2845 return data.error_set.abiAlignmentAdvanced(target, strat);
2846 }
2847 switch (data.error_set.abiAlignmentAdvanced(target, strat)) {
2848 .scalar => |err_set_align| {
2849 return .{ .scalar = @maximum(payload_align, err_set_align) };
2850 },
2851 .val => {},
2852 }
2853 },
2854 .val => {},
2855 }
2856 return .{ .val = Value.Tag.lazy_align.create(arena, ty) };
2857 },
2660 }2858 }
2661 return @maximum(
2662 data.payload.abiAlignment(target),
2663 data.error_set.abiAlignment(target),
2664 );
2665 },2859 },
26662860
2667 .@"struct" => {2861 .@"struct" => {
2668 const fields = self.structFields();2862 if (ty.castTag(.@"struct")) |payload| {
2669 if (self.castTag(.@"struct")) |payload| {
2670 const struct_obj = payload.data;2863 const struct_obj = payload.data;
2671 assert(struct_obj.haveLayout());2864 if (!struct_obj.haveLayout()) switch (strat) {
2865 .eager => unreachable, // struct layout not resolved
2866 .lazy => |arena| return .{ .val = Value.Tag.lazy_align.create(arena, ty) },
2867 };
2672 if (struct_obj.layout == .Packed) {2868 if (struct_obj.layout == .Packed) {
2673 var buf: Type.Payload.Bits = undefined;2869 var buf: Type.Payload.Bits = undefined;
2674 const int_ty = struct_obj.packedIntegerType(target, &buf);2870 const int_ty = struct_obj.packedIntegerType(target, &buf);
2675 return int_ty.abiAlignment(target);2871 return .{ .scalar = int_ty.abiAlignment(target) };
2676 }2872 }
2677 }2873 }
26782874
2875 const fields = ty.structFields();
2679 var big_align: u32 = 0;2876 var big_align: u32 = 0;
2680 for (fields.values()) |field| {2877 for (fields.values()) |field| {
2681 if (!field.ty.hasRuntimeBits()) continue;2878 if (!field.ty.hasRuntimeBits()) continue;
...@@ -2683,31 +2880,45 @@ pub const Type = extern union {...@@ -2683,31 +2880,45 @@ pub const Type = extern union {
2683 const field_align = field.normalAlignment(target);2880 const field_align = field.normalAlignment(target);
2684 big_align = @maximum(big_align, field_align);2881 big_align = @maximum(big_align, field_align);
2685 }2882 }
2686 return big_align;2883 return .{ .scalar = big_align };
2687 },2884 },
26882885
2689 .tuple, .anon_struct => {2886 .tuple, .anon_struct => {
2690 const tuple = self.tupleFields();2887 const tuple = ty.tupleFields();
2691 var big_align: u32 = 0;2888 var big_align: u32 = 0;
2692 for (tuple.types) |field_ty, i| {2889 for (tuple.types) |field_ty, i| {
2693 const val = tuple.values[i];2890 const val = tuple.values[i];
2694 if (val.tag() != .unreachable_value) continue; // comptime field2891 if (val.tag() != .unreachable_value) continue; // comptime field
2695 if (!field_ty.hasRuntimeBits()) continue;
26962892
2697 const field_align = field_ty.abiAlignment(target);2893 switch (field_ty.abiAlignmentAdvanced(target, strat)) {
2698 big_align = @maximum(big_align, field_align);2894 .scalar => |field_align| big_align = @maximum(big_align, field_align),
2895 .val => switch (strat) {
2896 .eager => unreachable, // field type alignment not resolved
2897 .lazy => |arena| return .{ .val = Value.Tag.lazy_align.create(arena, ty) },
2898 },
2899 }
2699 }2900 }
2700 return big_align;2901 return .{ .scalar = big_align };
2701 },2902 },
27022903
2703 .enum_full, .enum_nonexhaustive, .enum_simple, .enum_numbered => {2904 .enum_full, .enum_nonexhaustive, .enum_simple, .enum_numbered => {
2704 var buffer: Payload.Bits = undefined;2905 var buffer: Payload.Bits = undefined;
2705 const int_tag_ty = self.intTagType(&buffer);2906 const int_tag_ty = ty.intTagType(&buffer);
2706 return int_tag_ty.abiAlignment(target);2907 return .{ .scalar = int_tag_ty.abiAlignment(target) };
2908 },
2909 .@"union" => switch (strat) {
2910 .eager => {
2911 // TODO pass `true` for have_tag when unions have a safety tag
2912 return .{ .scalar = ty.castTag(.@"union").?.data.abiAlignment(target, false) };
2913 },
2914 .lazy => |arena| return .{ .val = Value.Tag.lazy_align.create(arena, ty) },
2915 },
2916 .union_tagged => switch (strat) {
2917 .eager => {
2918 return .{ .scalar = ty.castTag(.union_tagged).?.data.abiAlignment(target, true) };
2919 },
2920 .lazy => |arena| return .{ .val = Value.Tag.lazy_align.create(arena, ty) },
2707 },2921 },
2708 // TODO pass `true` for have_tag when unions have a safety tag
2709 .@"union" => return self.castTag(.@"union").?.data.abiAlignment(target, false),
2710 .union_tagged => return self.castTag(.union_tagged).?.data.abiAlignment(target, true),
27112922
2712 .empty_struct,2923 .empty_struct,
2713 .void,2924 .void,
...@@ -2719,7 +2930,7 @@ pub const Type = extern union {...@@ -2719,7 +2930,7 @@ pub const Type = extern union {
2719 .@"undefined",2930 .@"undefined",
2720 .enum_literal,2931 .enum_literal,
2721 .type_info,2932 .type_info,
2722 => return 0,2933 => return .{ .scalar = 0 },
27232934
2724 .noreturn,2935 .noreturn,
2725 .inferred_alloc_const,2936 .inferred_alloc_const,
...@@ -3392,10 +3603,7 @@ pub const Type = extern union {...@@ -3392,10 +3603,7 @@ pub const Type = extern union {
33923603
3393 .optional => {3604 .optional => {
3394 const child_ty = self.castTag(.optional).?.data;3605 const child_ty = self.castTag(.optional).?.data;
3395 // optionals of zero sized types behave like bools, not pointers
3396 if (!child_ty.hasRuntimeBits()) return false;
3397 if (child_ty.zigTypeTag() != .Pointer) return false;3606 if (child_ty.zigTypeTag() != .Pointer) return false;
3398
3399 const info = child_ty.ptrInfo().data;3607 const info = child_ty.ptrInfo().data;
3400 switch (info.size) {3608 switch (info.size) {
3401 .Slice, .C => return false,3609 .Slice, .C => return false,
...@@ -3663,9 +3871,9 @@ pub const Type = extern union {...@@ -3663,9 +3871,9 @@ pub const Type = extern union {
3663 return union_obj.fields;3871 return union_obj.fields;
3664 }3872 }
36653873
3666 pub fn unionFieldType(ty: Type, enum_tag: Value) Type {3874 pub fn unionFieldType(ty: Type, enum_tag: Value, target: Target) Type {
3667 const union_obj = ty.cast(Payload.Union).?.data;3875 const union_obj = ty.cast(Payload.Union).?.data;
3668 const index = union_obj.tag_ty.enumTagFieldIndex(enum_tag).?;3876 const index = union_obj.tag_ty.enumTagFieldIndex(enum_tag, target).?;
3669 assert(union_obj.haveFieldTypes());3877 assert(union_obj.haveFieldTypes());
3670 return union_obj.fields.values()[index].ty;3878 return union_obj.fields.values()[index].ty;
3671 }3879 }
...@@ -4679,20 +4887,20 @@ pub const Type = extern union {...@@ -4679,20 +4887,20 @@ pub const Type = extern union {
4679 /// Asserts `ty` is an enum. `enum_tag` can either be `enum_field_index` or4887 /// Asserts `ty` is an enum. `enum_tag` can either be `enum_field_index` or
4680 /// an integer which represents the enum value. Returns the field index in4888 /// an integer which represents the enum value. Returns the field index in
4681 /// declaration order, or `null` if `enum_tag` does not match any field.4889 /// declaration order, or `null` if `enum_tag` does not match any field.
4682 pub fn enumTagFieldIndex(ty: Type, enum_tag: Value) ?usize {4890 pub fn enumTagFieldIndex(ty: Type, enum_tag: Value, target: Target) ?usize {
4683 if (enum_tag.castTag(.enum_field_index)) |payload| {4891 if (enum_tag.castTag(.enum_field_index)) |payload| {
4684 return @as(usize, payload.data);4892 return @as(usize, payload.data);
4685 }4893 }
4686 const S = struct {4894 const S = struct {
4687 fn fieldWithRange(int_ty: Type, int_val: Value, end: usize) ?usize {4895 fn fieldWithRange(int_ty: Type, int_val: Value, end: usize, tg: Target) ?usize {
4688 if (int_val.compareWithZero(.lt)) return null;4896 if (int_val.compareWithZero(.lt)) return null;
4689 var end_payload: Value.Payload.U64 = .{4897 var end_payload: Value.Payload.U64 = .{
4690 .base = .{ .tag = .int_u64 },4898 .base = .{ .tag = .int_u64 },
4691 .data = end,4899 .data = end,
4692 };4900 };
4693 const end_val = Value.initPayload(&end_payload.base);4901 const end_val = Value.initPayload(&end_payload.base);
4694 if (int_val.compare(.gte, end_val, int_ty)) return null;4902 if (int_val.compare(.gte, end_val, int_ty, tg)) return null;
4695 return @intCast(usize, int_val.toUnsignedInt());4903 return @intCast(usize, int_val.toUnsignedInt(tg));
4696 }4904 }
4697 };4905 };
4698 switch (ty.tag()) {4906 switch (ty.tag()) {
...@@ -4700,18 +4908,24 @@ pub const Type = extern union {...@@ -4700,18 +4908,24 @@ pub const Type = extern union {
4700 const enum_full = ty.cast(Payload.EnumFull).?.data;4908 const enum_full = ty.cast(Payload.EnumFull).?.data;
4701 const tag_ty = enum_full.tag_ty;4909 const tag_ty = enum_full.tag_ty;
4702 if (enum_full.values.count() == 0) {4910 if (enum_full.values.count() == 0) {
4703 return S.fieldWithRange(tag_ty, enum_tag, enum_full.fields.count());4911 return S.fieldWithRange(tag_ty, enum_tag, enum_full.fields.count(), target);
4704 } else {4912 } else {
4705 return enum_full.values.getIndexContext(enum_tag, .{ .ty = tag_ty });4913 return enum_full.values.getIndexContext(enum_tag, .{
4914 .ty = tag_ty,
4915 .target = target,
4916 });
4706 }4917 }
4707 },4918 },
4708 .enum_numbered => {4919 .enum_numbered => {
4709 const enum_obj = ty.castTag(.enum_numbered).?.data;4920 const enum_obj = ty.castTag(.enum_numbered).?.data;
4710 const tag_ty = enum_obj.tag_ty;4921 const tag_ty = enum_obj.tag_ty;
4711 if (enum_obj.values.count() == 0) {4922 if (enum_obj.values.count() == 0) {
4712 return S.fieldWithRange(tag_ty, enum_tag, enum_obj.fields.count());4923 return S.fieldWithRange(tag_ty, enum_tag, enum_obj.fields.count(), target);
4713 } else {4924 } else {
4714 return enum_obj.values.getIndexContext(enum_tag, .{ .ty = tag_ty });4925 return enum_obj.values.getIndexContext(enum_tag, .{
4926 .ty = tag_ty,
4927 .target = target,
4928 });
4715 }4929 }
4716 },4930 },
4717 .enum_simple => {4931 .enum_simple => {
...@@ -4723,7 +4937,7 @@ pub const Type = extern union {...@@ -4723,7 +4937,7 @@ pub const Type = extern union {
4723 .data = bits,4937 .data = bits,
4724 };4938 };
4725 const tag_ty = Type.initPayload(&buffer.base);4939 const tag_ty = Type.initPayload(&buffer.base);
4726 return S.fieldWithRange(tag_ty, enum_tag, fields_len);4940 return S.fieldWithRange(tag_ty, enum_tag, fields_len, target);
4727 },4941 },
4728 .atomic_order,4942 .atomic_order,
4729 .atomic_rmw_op,4943 .atomic_rmw_op,
...@@ -5018,14 +5232,14 @@ pub const Type = extern union {...@@ -5018,14 +5232,14 @@ pub const Type = extern union {
5018 /// Asserts the type is an enum.5232 /// Asserts the type is an enum.
5019 pub fn enumHasInt(ty: Type, int: Value, target: Target) bool {5233 pub fn enumHasInt(ty: Type, int: Value, target: Target) bool {
5020 const S = struct {5234 const S = struct {
5021 fn intInRange(tag_ty: Type, int_val: Value, end: usize) bool {5235 fn intInRange(tag_ty: Type, int_val: Value, end: usize, tg: Target) bool {
5022 if (int_val.compareWithZero(.lt)) return false;5236 if (int_val.compareWithZero(.lt)) return false;
5023 var end_payload: Value.Payload.U64 = .{5237 var end_payload: Value.Payload.U64 = .{
5024 .base = .{ .tag = .int_u64 },5238 .base = .{ .tag = .int_u64 },
5025 .data = end,5239 .data = end,
5026 };5240 };
5027 const end_val = Value.initPayload(&end_payload.base);5241 const end_val = Value.initPayload(&end_payload.base);
5028 if (int_val.compare(.gte, end_val, tag_ty)) return false;5242 if (int_val.compare(.gte, end_val, tag_ty, tg)) return false;
5029 return true;5243 return true;
5030 }5244 }
5031 };5245 };
...@@ -5035,18 +5249,24 @@ pub const Type = extern union {...@@ -5035,18 +5249,24 @@ pub const Type = extern union {
5035 const enum_full = ty.castTag(.enum_full).?.data;5249 const enum_full = ty.castTag(.enum_full).?.data;
5036 const tag_ty = enum_full.tag_ty;5250 const tag_ty = enum_full.tag_ty;
5037 if (enum_full.values.count() == 0) {5251 if (enum_full.values.count() == 0) {
5038 return S.intInRange(tag_ty, int, enum_full.fields.count());5252 return S.intInRange(tag_ty, int, enum_full.fields.count(), target);
5039 } else {5253 } else {
5040 return enum_full.values.containsContext(int, .{ .ty = tag_ty });5254 return enum_full.values.containsContext(int, .{
5255 .ty = tag_ty,
5256 .target = target,
5257 });
5041 }5258 }
5042 },5259 },
5043 .enum_numbered => {5260 .enum_numbered => {
5044 const enum_obj = ty.castTag(.enum_numbered).?.data;5261 const enum_obj = ty.castTag(.enum_numbered).?.data;
5045 const tag_ty = enum_obj.tag_ty;5262 const tag_ty = enum_obj.tag_ty;
5046 if (enum_obj.values.count() == 0) {5263 if (enum_obj.values.count() == 0) {
5047 return S.intInRange(tag_ty, int, enum_obj.fields.count());5264 return S.intInRange(tag_ty, int, enum_obj.fields.count(), target);
5048 } else {5265 } else {
5049 return enum_obj.values.containsContext(int, .{ .ty = tag_ty });5266 return enum_obj.values.containsContext(int, .{
5267 .ty = tag_ty,
5268 .target = target,
5269 });
5050 }5270 }
5051 },5271 },
5052 .enum_simple => {5272 .enum_simple => {
...@@ -5058,7 +5278,7 @@ pub const Type = extern union {...@@ -5058,7 +5278,7 @@ pub const Type = extern union {
5058 .data = bits,5278 .data = bits,
5059 };5279 };
5060 const tag_ty = Type.initPayload(&buffer.base);5280 const tag_ty = Type.initPayload(&buffer.base);
5061 return S.intInRange(tag_ty, int, fields_len);5281 return S.intInRange(tag_ty, int, fields_len, target);
5062 },5282 },
5063 .atomic_order,5283 .atomic_order,
5064 .atomic_rmw_op,5284 .atomic_rmw_op,
...@@ -5070,7 +5290,7 @@ pub const Type = extern union {...@@ -5070,7 +5290,7 @@ pub const Type = extern union {
5070 .prefetch_options,5290 .prefetch_options,
5071 .export_options,5291 .export_options,
5072 .extern_options,5292 .extern_options,
5073 => @panic("TODO resolve std.builtin types"),5293 => unreachable,
50745294
5075 else => unreachable,5295 else => unreachable,
5076 }5296 }
...@@ -5620,7 +5840,7 @@ pub const Type = extern union {...@@ -5620,7 +5840,7 @@ pub const Type = extern union {
5620 d.bit_offset == 0 and d.host_size == 0 and !d.@"allowzero" and !d.@"volatile")5840 d.bit_offset == 0 and d.host_size == 0 and !d.@"allowzero" and !d.@"volatile")
5621 {5841 {
5622 if (d.sentinel) |sent| {5842 if (d.sentinel) |sent| {
5623 if (!d.mutable and d.pointee_type.eql(Type.u8)) {5843 if (!d.mutable and d.pointee_type.eql(Type.u8, target)) {
5624 switch (d.size) {5844 switch (d.size) {
5625 .Slice => {5845 .Slice => {
5626 if (sent.compareWithZero(.eq)) {5846 if (sent.compareWithZero(.eq)) {
...@@ -5635,7 +5855,7 @@ pub const Type = extern union {...@@ -5635,7 +5855,7 @@ pub const Type = extern union {
5635 else => {},5855 else => {},
5636 }5856 }
5637 }5857 }
5638 } else if (!d.mutable and d.pointee_type.eql(Type.u8)) {5858 } else if (!d.mutable and d.pointee_type.eql(Type.u8, target)) {
5639 switch (d.size) {5859 switch (d.size) {
5640 .Slice => return Type.initTag(.const_slice_u8),5860 .Slice => return Type.initTag(.const_slice_u8),
5641 .Many => return Type.initTag(.manyptr_const_u8),5861 .Many => return Type.initTag(.manyptr_const_u8),
...@@ -5669,10 +5889,11 @@ pub const Type = extern union {...@@ -5669,10 +5889,11 @@ pub const Type = extern union {
5669 len: u64,5889 len: u64,
5670 sent: ?Value,5890 sent: ?Value,
5671 elem_type: Type,5891 elem_type: Type,
5892 target: Target,
5672 ) Allocator.Error!Type {5893 ) Allocator.Error!Type {
5673 if (elem_type.eql(Type.u8)) {5894 if (elem_type.eql(Type.u8, target)) {
5674 if (sent) |some| {5895 if (sent) |some| {
5675 if (some.eql(Value.zero, elem_type)) {5896 if (some.eql(Value.zero, elem_type, target)) {
5676 return Tag.array_u8_sentinel_0.create(arena, len);5897 return Tag.array_u8_sentinel_0.create(arena, len);
5677 }5898 }
5678 } else {5899 } else {
...@@ -5715,6 +5936,25 @@ pub const Type = extern union {...@@ -5715,6 +5936,25 @@ pub const Type = extern union {
5715 }5936 }
5716 }5937 }
57175938
5939 pub fn errorUnion(
5940 arena: Allocator,
5941 error_set: Type,
5942 payload: Type,
5943 target: Target,
5944 ) Allocator.Error!Type {
5945 assert(error_set.zigTypeTag() == .ErrorSet);
5946 if (error_set.eql(Type.@"anyerror", target) and
5947 payload.eql(Type.void, target))
5948 {
5949 return Type.initTag(.anyerror_void_error_union);
5950 }
5951
5952 return Type.Tag.error_union.create(arena, .{
5953 .error_set = error_set,
5954 .payload = payload,
5955 });
5956 }
5957
5718 pub fn smallestUnsignedBits(max: u64) u16 {5958 pub fn smallestUnsignedBits(max: u64) u16 {
5719 if (max == 0) return 0;5959 if (max == 0) return 0;
5720 const base = std.math.log2(max);5960 const base = std.math.log2(max);
src/value.zig+258-206
...@@ -8,6 +8,7 @@ const Target = std.Target;...@@ -8,6 +8,7 @@ const Target = std.Target;
8const Allocator = std.mem.Allocator;8const Allocator = std.mem.Allocator;
9const Module = @import("Module.zig");9const Module = @import("Module.zig");
10const Air = @import("Air.zig");10const Air = @import("Air.zig");
11const TypedValue = @import("TypedValue.zig");
1112
12/// This is the raw data, with no bookkeeping, no memory awareness,13/// This is the raw data, with no bookkeeping, no memory awareness,
13/// no de-duplication, and no type system awareness.14/// no de-duplication, and no type system awareness.
...@@ -175,6 +176,8 @@ pub const Value = extern union {...@@ -175,6 +176,8 @@ pub const Value = extern union {
175 /// and refers directly to the air. It will never be referenced by the air itself.176 /// and refers directly to the air. It will never be referenced by the air itself.
176 /// TODO: This is probably a bad encoding, maybe put temp data in the sema instead.177 /// TODO: This is probably a bad encoding, maybe put temp data in the sema instead.
177 bound_fn,178 bound_fn,
179 /// The ABI alignment of the payload type.
180 lazy_align,
178181
179 pub const last_no_payload_tag = Tag.empty_array;182 pub const last_no_payload_tag = Tag.empty_array;
180 pub const no_payload_count = @enumToInt(last_no_payload_tag) + 1;183 pub const no_payload_count = @enumToInt(last_no_payload_tag) + 1;
...@@ -283,7 +286,10 @@ pub const Value = extern union {...@@ -283,7 +286,10 @@ pub const Value = extern union {
283286
284 .enum_field_index => Payload.U32,287 .enum_field_index => Payload.U32,
285288
286 .ty => Payload.Ty,289 .ty,
290 .lazy_align,
291 => Payload.Ty,
292
287 .int_type => Payload.IntType,293 .int_type => Payload.IntType,
288 .int_u64 => Payload.U64,294 .int_u64 => Payload.U64,
289 .int_i64 => Payload.I64,295 .int_i64 => Payload.I64,
...@@ -453,7 +459,7 @@ pub const Value = extern union {...@@ -453,7 +459,7 @@ pub const Value = extern union {
453 .bound_fn,459 .bound_fn,
454 => unreachable,460 => unreachable,
455461
456 .ty => {462 .ty, .lazy_align => {
457 const payload = self.castTag(.ty).?;463 const payload = self.castTag(.ty).?;
458 const new_payload = try arena.create(Payload.Ty);464 const new_payload = try arena.create(Payload.Ty);
459 new_payload.* = .{465 new_payload.* = .{
...@@ -608,7 +614,7 @@ pub const Value = extern union {...@@ -608,7 +614,7 @@ pub const Value = extern union {
608 @compileError("do not use format values directly; use either fmtDebug or fmtValue");614 @compileError("do not use format values directly; use either fmtDebug or fmtValue");
609 }615 }
610616
611 /// TODO this should become a debug dump() function. In order to print values in a meaningful way617 /// This is a debug function. In order to print values in a meaningful way
612 /// we also need access to the type.618 /// we also need access to the type.
613 pub fn dump(619 pub fn dump(
614 start_val: Value,620 start_val: Value,
...@@ -699,7 +705,12 @@ pub const Value = extern union {...@@ -699,7 +705,12 @@ pub const Value = extern union {
699 .the_only_possible_value => return out_stream.writeAll("(the only possible value)"),705 .the_only_possible_value => return out_stream.writeAll("(the only possible value)"),
700 .bool_true => return out_stream.writeAll("true"),706 .bool_true => return out_stream.writeAll("true"),
701 .bool_false => return out_stream.writeAll("false"),707 .bool_false => return out_stream.writeAll("false"),
702 .ty => return val.castTag(.ty).?.data.format("", options, out_stream),708 .ty => return val.castTag(.ty).?.data.dump("", options, out_stream),
709 .lazy_align => {
710 try out_stream.writeAll("@alignOf(");
711 try val.castTag(.lazy_align).?.data.dump("", options, out_stream);
712 try out_stream.writeAll(")");
713 },
703 .int_type => {714 .int_type => {
704 const int_type = val.castTag(.int_type).?.data;715 const int_type = val.castTag(.int_type).?.data;
705 return out_stream.print("{s}{d}", .{716 return out_stream.print("{s}{d}", .{
...@@ -778,15 +789,16 @@ pub const Value = extern union {...@@ -778,15 +789,16 @@ pub const Value = extern union {
778 return .{ .data = val };789 return .{ .data = val };
779 }790 }
780791
781 const TypedValue = @import("TypedValue.zig");792 pub fn fmtValue(val: Value, ty: Type, target: Target) std.fmt.Formatter(TypedValue.format) {
782793 return .{ .data = .{
783 pub fn fmtValue(val: Value, ty: Type) std.fmt.Formatter(TypedValue.format) {794 .tv = .{ .ty = ty, .val = val },
784 return .{ .data = .{ .ty = ty, .val = val } };795 .target = target,
796 } };
785 }797 }
786798
787 /// Asserts that the value is representable as an array of bytes.799 /// Asserts that the value is representable as an array of bytes.
788 /// Copies the value into a freshly allocated slice of memory, which is owned by the caller.800 /// Copies the value into a freshly allocated slice of memory, which is owned by the caller.
789 pub fn toAllocatedBytes(val: Value, ty: Type, allocator: Allocator) ![]u8 {801 pub fn toAllocatedBytes(val: Value, ty: Type, allocator: Allocator, target: Target) ![]u8 {
790 switch (val.tag()) {802 switch (val.tag()) {
791 .bytes => {803 .bytes => {
792 const bytes = val.castTag(.bytes).?.data;804 const bytes = val.castTag(.bytes).?.data;
...@@ -796,7 +808,7 @@ pub const Value = extern union {...@@ -796,7 +808,7 @@ pub const Value = extern union {
796 },808 },
797 .enum_literal => return allocator.dupe(u8, val.castTag(.enum_literal).?.data),809 .enum_literal => return allocator.dupe(u8, val.castTag(.enum_literal).?.data),
798 .repeated => {810 .repeated => {
799 const byte = @intCast(u8, val.castTag(.repeated).?.data.toUnsignedInt());811 const byte = @intCast(u8, val.castTag(.repeated).?.data.toUnsignedInt(target));
800 const result = try allocator.alloc(u8, @intCast(usize, ty.arrayLen()));812 const result = try allocator.alloc(u8, @intCast(usize, ty.arrayLen()));
801 std.mem.set(u8, result, byte);813 std.mem.set(u8, result, byte);
802 return result;814 return result;
...@@ -804,23 +816,23 @@ pub const Value = extern union {...@@ -804,23 +816,23 @@ pub const Value = extern union {
804 .decl_ref => {816 .decl_ref => {
805 const decl = val.castTag(.decl_ref).?.data;817 const decl = val.castTag(.decl_ref).?.data;
806 const decl_val = try decl.value();818 const decl_val = try decl.value();
807 return decl_val.toAllocatedBytes(decl.ty, allocator);819 return decl_val.toAllocatedBytes(decl.ty, allocator, target);
808 },820 },
809 .the_only_possible_value => return &[_]u8{},821 .the_only_possible_value => return &[_]u8{},
810 .slice => {822 .slice => {
811 const slice = val.castTag(.slice).?.data;823 const slice = val.castTag(.slice).?.data;
812 return arrayToAllocatedBytes(slice.ptr, slice.len.toUnsignedInt(), allocator);824 return arrayToAllocatedBytes(slice.ptr, slice.len.toUnsignedInt(target), allocator, target);
813 },825 },
814 else => return arrayToAllocatedBytes(val, ty.arrayLen(), allocator),826 else => return arrayToAllocatedBytes(val, ty.arrayLen(), allocator, target),
815 }827 }
816 }828 }
817829
818 fn arrayToAllocatedBytes(val: Value, len: u64, allocator: Allocator) ![]u8 {830 fn arrayToAllocatedBytes(val: Value, len: u64, allocator: Allocator, target: Target) ![]u8 {
819 const result = try allocator.alloc(u8, @intCast(usize, len));831 const result = try allocator.alloc(u8, @intCast(usize, len));
820 var elem_value_buf: ElemValueBuffer = undefined;832 var elem_value_buf: ElemValueBuffer = undefined;
821 for (result) |*elem, i| {833 for (result) |*elem, i| {
822 const elem_val = val.elemValueBuffer(i, &elem_value_buf);834 const elem_val = val.elemValueBuffer(i, &elem_value_buf);
823 elem.* = @intCast(u8, elem_val.toUnsignedInt());835 elem.* = @intCast(u8, elem_val.toUnsignedInt(target));
824 }836 }
825 return result;837 return result;
826 }838 }
...@@ -977,8 +989,8 @@ pub const Value = extern union {...@@ -977,8 +989,8 @@ pub const Value = extern union {
977 }989 }
978990
979 /// Asserts the value is an integer.991 /// Asserts the value is an integer.
980 pub fn toBigInt(self: Value, space: *BigIntSpace) BigIntConst {992 pub fn toBigInt(val: Value, space: *BigIntSpace, target: Target) BigIntConst {
981 switch (self.tag()) {993 switch (val.tag()) {
982 .zero,994 .zero,
983 .bool_false,995 .bool_false,
984 .the_only_possible_value, // i0, u0996 .the_only_possible_value, // i0, u0
...@@ -988,19 +1000,25 @@ pub const Value = extern union {...@@ -988,19 +1000,25 @@ pub const Value = extern union {
988 .bool_true,1000 .bool_true,
989 => return BigIntMutable.init(&space.limbs, 1).toConst(),1001 => return BigIntMutable.init(&space.limbs, 1).toConst(),
9901002
991 .int_u64 => return BigIntMutable.init(&space.limbs, self.castTag(.int_u64).?.data).toConst(),1003 .int_u64 => return BigIntMutable.init(&space.limbs, val.castTag(.int_u64).?.data).toConst(),
992 .int_i64 => return BigIntMutable.init(&space.limbs, self.castTag(.int_i64).?.data).toConst(),1004 .int_i64 => return BigIntMutable.init(&space.limbs, val.castTag(.int_i64).?.data).toConst(),
993 .int_big_positive => return self.castTag(.int_big_positive).?.asBigInt(),1005 .int_big_positive => return val.castTag(.int_big_positive).?.asBigInt(),
994 .int_big_negative => return self.castTag(.int_big_negative).?.asBigInt(),1006 .int_big_negative => return val.castTag(.int_big_negative).?.asBigInt(),
9951007
996 .undef => unreachable,1008 .undef => unreachable,
1009
1010 .lazy_align => {
1011 const x = val.castTag(.lazy_align).?.data.abiAlignment(target);
1012 return BigIntMutable.init(&space.limbs, x).toConst();
1013 },
1014
997 else => unreachable,1015 else => unreachable,
998 }1016 }
999 }1017 }
10001018
1001 /// If the value fits in a u64, return it, otherwise null.1019 /// If the value fits in a u64, return it, otherwise null.
1002 /// Asserts not undefined.1020 /// Asserts not undefined.
1003 pub fn getUnsignedInt(val: Value) ?u64 {1021 pub fn getUnsignedInt(val: Value, target: Target) ?u64 {
1004 switch (val.tag()) {1022 switch (val.tag()) {
1005 .zero,1023 .zero,
1006 .bool_false,1024 .bool_false,
...@@ -1017,13 +1035,16 @@ pub const Value = extern union {...@@ -1017,13 +1035,16 @@ pub const Value = extern union {
1017 .int_big_negative => return val.castTag(.int_big_negative).?.asBigInt().to(u64) catch null,1035 .int_big_negative => return val.castTag(.int_big_negative).?.asBigInt().to(u64) catch null,
10181036
1019 .undef => unreachable,1037 .undef => unreachable,
1038
1039 .lazy_align => return val.castTag(.lazy_align).?.data.abiAlignment(target),
1040
1020 else => return null,1041 else => return null,
1021 }1042 }
1022 }1043 }
10231044
1024 /// Asserts the value is an integer and it fits in a u641045 /// Asserts the value is an integer and it fits in a u64
1025 pub fn toUnsignedInt(val: Value) u64 {1046 pub fn toUnsignedInt(val: Value, target: Target) u64 {
1026 return getUnsignedInt(val).?;1047 return getUnsignedInt(val, target).?;
1027 }1048 }
10281049
1029 /// Asserts the value is an integer and it fits in a i641050 /// Asserts the value is an integer and it fits in a i64
...@@ -1066,7 +1087,7 @@ pub const Value = extern union {...@@ -1066,7 +1087,7 @@ pub const Value = extern union {
1066 switch (ty.zigTypeTag()) {1087 switch (ty.zigTypeTag()) {
1067 .Int => {1088 .Int => {
1068 var bigint_buffer: BigIntSpace = undefined;1089 var bigint_buffer: BigIntSpace = undefined;
1069 const bigint = val.toBigInt(&bigint_buffer);1090 const bigint = val.toBigInt(&bigint_buffer, target);
1070 const bits = ty.intInfo(target).bits;1091 const bits = ty.intInfo(target).bits;
1071 const abi_size = @intCast(usize, ty.abiSize(target));1092 const abi_size = @intCast(usize, ty.abiSize(target));
1072 bigint.writeTwosComplement(buffer, bits, abi_size, target.cpu.arch.endian());1093 bigint.writeTwosComplement(buffer, bits, abi_size, target.cpu.arch.endian());
...@@ -1075,7 +1096,7 @@ pub const Value = extern union {...@@ -1075,7 +1096,7 @@ pub const Value = extern union {
1075 var enum_buffer: Payload.U64 = undefined;1096 var enum_buffer: Payload.U64 = undefined;
1076 const int_val = val.enumToInt(ty, &enum_buffer);1097 const int_val = val.enumToInt(ty, &enum_buffer);
1077 var bigint_buffer: BigIntSpace = undefined;1098 var bigint_buffer: BigIntSpace = undefined;
1078 const bigint = int_val.toBigInt(&bigint_buffer);1099 const bigint = int_val.toBigInt(&bigint_buffer, target);
1079 const bits = ty.intInfo(target).bits;1100 const bits = ty.intInfo(target).bits;
1080 const abi_size = @intCast(usize, ty.abiSize(target));1101 const abi_size = @intCast(usize, ty.abiSize(target));
1081 bigint.writeTwosComplement(buffer, bits, abi_size, target.cpu.arch.endian());1102 bigint.writeTwosComplement(buffer, bits, abi_size, target.cpu.arch.endian());
...@@ -1151,7 +1172,7 @@ pub const Value = extern union {...@@ -1151,7 +1172,7 @@ pub const Value = extern union {
1151 128 => bitcastFloatToBigInt(f128, val.toFloat(f128), &field_buf),1172 128 => bitcastFloatToBigInt(f128, val.toFloat(f128), &field_buf),
1152 else => unreachable,1173 else => unreachable,
1153 },1174 },
1154 .Int, .Bool => field_val.toBigInt(&field_space),1175 .Int, .Bool => field_val.toBigInt(&field_space, target),
1155 .Struct => packedStructToInt(field_val, field.ty, target, &field_buf),1176 .Struct => packedStructToInt(field_val, field.ty, target, &field_buf),
1156 else => unreachable,1177 else => unreachable,
1157 };1178 };
...@@ -1511,7 +1532,7 @@ pub const Value = extern union {...@@ -1511,7 +1532,7 @@ pub const Value = extern union {
1511 const info = ty.intInfo(target);1532 const info = ty.intInfo(target);
15121533
1513 var buffer: Value.BigIntSpace = undefined;1534 var buffer: Value.BigIntSpace = undefined;
1514 const operand_bigint = val.toBigInt(&buffer);1535 const operand_bigint = val.toBigInt(&buffer, target);
15151536
1516 var limbs_buffer: [4]std.math.big.Limb = undefined;1537 var limbs_buffer: [4]std.math.big.Limb = undefined;
1517 var result_bigint = BigIntMutable{1538 var result_bigint = BigIntMutable{
...@@ -1532,7 +1553,7 @@ pub const Value = extern union {...@@ -1532,7 +1553,7 @@ pub const Value = extern union {
1532 const info = ty.intInfo(target);1553 const info = ty.intInfo(target);
15331554
1534 var buffer: Value.BigIntSpace = undefined;1555 var buffer: Value.BigIntSpace = undefined;
1535 const operand_bigint = val.toBigInt(&buffer);1556 const operand_bigint = val.toBigInt(&buffer, target);
15361557
1537 const limbs = try arena.alloc(1558 const limbs = try arena.alloc(
1538 std.math.big.Limb,1559 std.math.big.Limb,
...@@ -1553,7 +1574,7 @@ pub const Value = extern union {...@@ -1553,7 +1574,7 @@ pub const Value = extern union {
1553 assert(info.bits % 8 == 0);1574 assert(info.bits % 8 == 0);
15541575
1555 var buffer: Value.BigIntSpace = undefined;1576 var buffer: Value.BigIntSpace = undefined;
1556 const operand_bigint = val.toBigInt(&buffer);1577 const operand_bigint = val.toBigInt(&buffer, target);
15571578
1558 const limbs = try arena.alloc(1579 const limbs = try arena.alloc(
1559 std.math.big.Limb,1580 std.math.big.Limb,
...@@ -1597,7 +1618,7 @@ pub const Value = extern union {...@@ -1597,7 +1618,7 @@ pub const Value = extern union {
15971618
1598 else => {1619 else => {
1599 var buffer: BigIntSpace = undefined;1620 var buffer: BigIntSpace = undefined;
1600 return self.toBigInt(&buffer).bitCountTwosComp();1621 return self.toBigInt(&buffer, target).bitCountTwosComp();
1601 },1622 },
1602 }1623 }
1603 }1624 }
...@@ -1624,6 +1645,17 @@ pub const Value = extern union {...@@ -1624,6 +1645,17 @@ pub const Value = extern union {
1624 else => unreachable,1645 else => unreachable,
1625 },1646 },
16261647
1648 .lazy_align => {
1649 const info = ty.intInfo(target);
1650 const max_needed_bits = @as(u16, 16) + @boolToInt(info.signedness == .signed);
1651 // If it is u16 or bigger we know the alignment fits without resolving it.
1652 if (info.bits >= max_needed_bits) return true;
1653 const x = self.castTag(.lazy_align).?.data.abiAlignment(target);
1654 if (x == 0) return true;
1655 const actual_needed_bits = std.math.log2(x) + 1 + @boolToInt(info.signedness == .signed);
1656 return info.bits >= actual_needed_bits;
1657 },
1658
1627 .int_u64 => switch (ty.zigTypeTag()) {1659 .int_u64 => switch (ty.zigTypeTag()) {
1628 .Int => {1660 .Int => {
1629 const x = self.castTag(.int_u64).?.data;1661 const x = self.castTag(.int_u64).?.data;
...@@ -1643,7 +1675,7 @@ pub const Value = extern union {...@@ -1643,7 +1675,7 @@ pub const Value = extern union {
1643 if (info.signedness == .unsigned and x < 0)1675 if (info.signedness == .unsigned and x < 0)
1644 return false;1676 return false;
1645 var buffer: BigIntSpace = undefined;1677 var buffer: BigIntSpace = undefined;
1646 return self.toBigInt(&buffer).fitsInTwosComp(info.signedness, info.bits);1678 return self.toBigInt(&buffer, target).fitsInTwosComp(info.signedness, info.bits);
1647 },1679 },
1648 .ComptimeInt => return true,1680 .ComptimeInt => return true,
1649 else => unreachable,1681 else => unreachable,
...@@ -1765,6 +1797,15 @@ pub const Value = extern union {...@@ -1765,6 +1797,15 @@ pub const Value = extern union {
1765 .int_big_positive => lhs.castTag(.int_big_positive).?.asBigInt().orderAgainstScalar(0),1797 .int_big_positive => lhs.castTag(.int_big_positive).?.asBigInt().orderAgainstScalar(0),
1766 .int_big_negative => lhs.castTag(.int_big_negative).?.asBigInt().orderAgainstScalar(0),1798 .int_big_negative => lhs.castTag(.int_big_negative).?.asBigInt().orderAgainstScalar(0),
17671799
1800 .lazy_align => {
1801 const ty = lhs.castTag(.lazy_align).?.data;
1802 if (ty.hasRuntimeBitsIgnoreComptime()) {
1803 return .gt;
1804 } else {
1805 return .eq;
1806 }
1807 },
1808
1768 .float_16 => std.math.order(lhs.castTag(.float_16).?.data, 0),1809 .float_16 => std.math.order(lhs.castTag(.float_16).?.data, 0),
1769 .float_32 => std.math.order(lhs.castTag(.float_32).?.data, 0),1810 .float_32 => std.math.order(lhs.castTag(.float_32).?.data, 0),
1770 .float_64 => std.math.order(lhs.castTag(.float_64).?.data, 0),1811 .float_64 => std.math.order(lhs.castTag(.float_64).?.data, 0),
...@@ -1776,7 +1817,7 @@ pub const Value = extern union {...@@ -1776,7 +1817,7 @@ pub const Value = extern union {
1776 }1817 }
17771818
1778 /// Asserts the value is comparable.1819 /// Asserts the value is comparable.
1779 pub fn order(lhs: Value, rhs: Value) std.math.Order {1820 pub fn order(lhs: Value, rhs: Value, target: Target) std.math.Order {
1780 const lhs_tag = lhs.tag();1821 const lhs_tag = lhs.tag();
1781 const rhs_tag = rhs.tag();1822 const rhs_tag = rhs.tag();
1782 const lhs_against_zero = lhs.orderAgainstZero();1823 const lhs_against_zero = lhs.orderAgainstZero();
...@@ -1814,14 +1855,14 @@ pub const Value = extern union {...@@ -1814,14 +1855,14 @@ pub const Value = extern union {
18141855
1815 var lhs_bigint_space: BigIntSpace = undefined;1856 var lhs_bigint_space: BigIntSpace = undefined;
1816 var rhs_bigint_space: BigIntSpace = undefined;1857 var rhs_bigint_space: BigIntSpace = undefined;
1817 const lhs_bigint = lhs.toBigInt(&lhs_bigint_space);1858 const lhs_bigint = lhs.toBigInt(&lhs_bigint_space, target);
1818 const rhs_bigint = rhs.toBigInt(&rhs_bigint_space);1859 const rhs_bigint = rhs.toBigInt(&rhs_bigint_space, target);
1819 return lhs_bigint.order(rhs_bigint);1860 return lhs_bigint.order(rhs_bigint);
1820 }1861 }
18211862
1822 /// Asserts the value is comparable. Does not take a type parameter because it supports1863 /// Asserts the value is comparable. Does not take a type parameter because it supports
1823 /// comparisons between heterogeneous types.1864 /// comparisons between heterogeneous types.
1824 pub fn compareHetero(lhs: Value, op: std.math.CompareOperator, rhs: Value) bool {1865 pub fn compareHetero(lhs: Value, op: std.math.CompareOperator, rhs: Value, target: Target) bool {
1825 if (lhs.pointerDecl()) |lhs_decl| {1866 if (lhs.pointerDecl()) |lhs_decl| {
1826 if (rhs.pointerDecl()) |rhs_decl| {1867 if (rhs.pointerDecl()) |rhs_decl| {
1827 switch (op) {1868 switch (op) {
...@@ -1843,39 +1884,39 @@ pub const Value = extern union {...@@ -1843,39 +1884,39 @@ pub const Value = extern union {
1843 else => {},1884 else => {},
1844 }1885 }
1845 }1886 }
1846 return order(lhs, rhs).compare(op);1887 return order(lhs, rhs, target).compare(op);
1847 }1888 }
18481889
1849 /// Asserts the values are comparable. Both operands have type `ty`.1890 /// Asserts the values are comparable. Both operands have type `ty`.
1850 /// Vector results will be reduced with AND.1891 /// Vector results will be reduced with AND.
1851 pub fn compare(lhs: Value, op: std.math.CompareOperator, rhs: Value, ty: Type) bool {1892 pub fn compare(lhs: Value, op: std.math.CompareOperator, rhs: Value, ty: Type, target: Target) bool {
1852 if (ty.zigTypeTag() == .Vector) {1893 if (ty.zigTypeTag() == .Vector) {
1853 var i: usize = 0;1894 var i: usize = 0;
1854 while (i < ty.vectorLen()) : (i += 1) {1895 while (i < ty.vectorLen()) : (i += 1) {
1855 if (!compareScalar(lhs.indexVectorlike(i), op, rhs.indexVectorlike(i), ty.scalarType())) {1896 if (!compareScalar(lhs.indexVectorlike(i), op, rhs.indexVectorlike(i), ty.scalarType(), target)) {
1856 return false;1897 return false;
1857 }1898 }
1858 }1899 }
1859 return true;1900 return true;
1860 }1901 }
1861 return compareScalar(lhs, op, rhs, ty);1902 return compareScalar(lhs, op, rhs, ty, target);
1862 }1903 }
18631904
1864 /// Asserts the values are comparable. Both operands have type `ty`.1905 /// Asserts the values are comparable. Both operands have type `ty`.
1865 pub fn compareScalar(lhs: Value, op: std.math.CompareOperator, rhs: Value, ty: Type) bool {1906 pub fn compareScalar(lhs: Value, op: std.math.CompareOperator, rhs: Value, ty: Type, target: Target) bool {
1866 return switch (op) {1907 return switch (op) {
1867 .eq => lhs.eql(rhs, ty),1908 .eq => lhs.eql(rhs, ty, target),
1868 .neq => !lhs.eql(rhs, ty),1909 .neq => !lhs.eql(rhs, ty, target),
1869 else => compareHetero(lhs, op, rhs),1910 else => compareHetero(lhs, op, rhs, target),
1870 };1911 };
1871 }1912 }
18721913
1873 /// Asserts the values are comparable vectors of type `ty`.1914 /// Asserts the values are comparable vectors of type `ty`.
1874 pub fn compareVector(lhs: Value, op: std.math.CompareOperator, rhs: Value, ty: Type, allocator: Allocator) !Value {1915 pub fn compareVector(lhs: Value, op: std.math.CompareOperator, rhs: Value, ty: Type, allocator: Allocator, target: Target) !Value {
1875 assert(ty.zigTypeTag() == .Vector);1916 assert(ty.zigTypeTag() == .Vector);
1876 const result_data = try allocator.alloc(Value, ty.vectorLen());1917 const result_data = try allocator.alloc(Value, ty.vectorLen());
1877 for (result_data) |*scalar, i| {1918 for (result_data) |*scalar, i| {
1878 const res_bool = compareScalar(lhs.indexVectorlike(i), op, rhs.indexVectorlike(i), ty.scalarType());1919 const res_bool = compareScalar(lhs.indexVectorlike(i), op, rhs.indexVectorlike(i), ty.scalarType(), target);
1879 scalar.* = if (res_bool) Value.@"true" else Value.@"false";1920 scalar.* = if (res_bool) Value.@"true" else Value.@"false";
1880 }1921 }
1881 return Value.Tag.aggregate.create(allocator, result_data);1922 return Value.Tag.aggregate.create(allocator, result_data);
...@@ -1899,12 +1940,12 @@ pub const Value = extern union {...@@ -1899,12 +1940,12 @@ pub const Value = extern union {
18991940
1900 /// This function is used by hash maps and so treats floating-point NaNs as equal1941 /// This function is used by hash maps and so treats floating-point NaNs as equal
1901 /// to each other, and not equal to other floating-point values.1942 /// to each other, and not equal to other floating-point values.
1902 pub fn eql(a: Value, b: Value, ty: Type) bool {1943 /// Similarly, it treats `undef` as a distinct value from all other values.
1944 pub fn eql(a: Value, b: Value, ty: Type, target: Target) bool {
1903 const a_tag = a.tag();1945 const a_tag = a.tag();
1904 const b_tag = b.tag();1946 const b_tag = b.tag();
1905 assert(a_tag != .undef);
1906 assert(b_tag != .undef);
1907 if (a_tag == b_tag) switch (a_tag) {1947 if (a_tag == b_tag) switch (a_tag) {
1948 .undef => return true,
1908 .void_value, .null_value, .the_only_possible_value, .empty_struct_value => return true,1949 .void_value, .null_value, .the_only_possible_value, .empty_struct_value => return true,
1909 .enum_literal => {1950 .enum_literal => {
1910 const a_name = a.castTag(.enum_literal).?.data;1951 const a_name = a.castTag(.enum_literal).?.data;
...@@ -1920,31 +1961,31 @@ pub const Value = extern union {...@@ -1920,31 +1961,31 @@ pub const Value = extern union {
1920 const a_payload = a.castTag(.opt_payload).?.data;1961 const a_payload = a.castTag(.opt_payload).?.data;
1921 const b_payload = b.castTag(.opt_payload).?.data;1962 const b_payload = b.castTag(.opt_payload).?.data;
1922 var buffer: Type.Payload.ElemType = undefined;1963 var buffer: Type.Payload.ElemType = undefined;
1923 return eql(a_payload, b_payload, ty.optionalChild(&buffer));1964 return eql(a_payload, b_payload, ty.optionalChild(&buffer), target);
1924 },1965 },
1925 .slice => {1966 .slice => {
1926 const a_payload = a.castTag(.slice).?.data;1967 const a_payload = a.castTag(.slice).?.data;
1927 const b_payload = b.castTag(.slice).?.data;1968 const b_payload = b.castTag(.slice).?.data;
1928 if (!eql(a_payload.len, b_payload.len, Type.usize)) return false;1969 if (!eql(a_payload.len, b_payload.len, Type.usize, target)) return false;
19291970
1930 var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;1971 var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;
1931 const ptr_ty = ty.slicePtrFieldType(&ptr_buf);1972 const ptr_ty = ty.slicePtrFieldType(&ptr_buf);
19321973
1933 return eql(a_payload.ptr, b_payload.ptr, ptr_ty);1974 return eql(a_payload.ptr, b_payload.ptr, ptr_ty, target);
1934 },1975 },
1935 .elem_ptr => {1976 .elem_ptr => {
1936 const a_payload = a.castTag(.elem_ptr).?.data;1977 const a_payload = a.castTag(.elem_ptr).?.data;
1937 const b_payload = b.castTag(.elem_ptr).?.data;1978 const b_payload = b.castTag(.elem_ptr).?.data;
1938 if (a_payload.index != b_payload.index) return false;1979 if (a_payload.index != b_payload.index) return false;
19391980
1940 return eql(a_payload.array_ptr, b_payload.array_ptr, ty);1981 return eql(a_payload.array_ptr, b_payload.array_ptr, ty, target);
1941 },1982 },
1942 .field_ptr => {1983 .field_ptr => {
1943 const a_payload = a.castTag(.field_ptr).?.data;1984 const a_payload = a.castTag(.field_ptr).?.data;
1944 const b_payload = b.castTag(.field_ptr).?.data;1985 const b_payload = b.castTag(.field_ptr).?.data;
1945 if (a_payload.field_index != b_payload.field_index) return false;1986 if (a_payload.field_index != b_payload.field_index) return false;
19461987
1947 return eql(a_payload.container_ptr, b_payload.container_ptr, ty);1988 return eql(a_payload.container_ptr, b_payload.container_ptr, ty, target);
1948 },1989 },
1949 .@"error" => {1990 .@"error" => {
1950 const a_name = a.castTag(.@"error").?.data.name;1991 const a_name = a.castTag(.@"error").?.data.name;
...@@ -1954,7 +1995,7 @@ pub const Value = extern union {...@@ -1954,7 +1995,7 @@ pub const Value = extern union {
1954 .eu_payload => {1995 .eu_payload => {
1955 const a_payload = a.castTag(.eu_payload).?.data;1996 const a_payload = a.castTag(.eu_payload).?.data;
1956 const b_payload = b.castTag(.eu_payload).?.data;1997 const b_payload = b.castTag(.eu_payload).?.data;
1957 return eql(a_payload, b_payload, ty.errorUnionPayload());1998 return eql(a_payload, b_payload, ty.errorUnionPayload(), target);
1958 },1999 },
1959 .eu_payload_ptr => @panic("TODO: Implement more pointer eql cases"),2000 .eu_payload_ptr => @panic("TODO: Implement more pointer eql cases"),
1960 .opt_payload_ptr => @panic("TODO: Implement more pointer eql cases"),2001 .opt_payload_ptr => @panic("TODO: Implement more pointer eql cases"),
...@@ -1972,7 +2013,7 @@ pub const Value = extern union {...@@ -1972,7 +2013,7 @@ pub const Value = extern union {
1972 const types = ty.tupleFields().types;2013 const types = ty.tupleFields().types;
1973 assert(types.len == a_field_vals.len);2014 assert(types.len == a_field_vals.len);
1974 for (types) |field_ty, i| {2015 for (types) |field_ty, i| {
1975 if (!eql(a_field_vals[i], b_field_vals[i], field_ty)) return false;2016 if (!eql(a_field_vals[i], b_field_vals[i], field_ty, target)) return false;
1976 }2017 }
1977 return true;2018 return true;
1978 }2019 }
...@@ -1981,7 +2022,7 @@ pub const Value = extern union {...@@ -1981,7 +2022,7 @@ pub const Value = extern union {
1981 const fields = ty.structFields().values();2022 const fields = ty.structFields().values();
1982 assert(fields.len == a_field_vals.len);2023 assert(fields.len == a_field_vals.len);
1983 for (fields) |field, i| {2024 for (fields) |field, i| {
1984 if (!eql(a_field_vals[i], b_field_vals[i], field.ty)) return false;2025 if (!eql(a_field_vals[i], b_field_vals[i], field.ty, target)) return false;
1985 }2026 }
1986 return true;2027 return true;
1987 }2028 }
...@@ -1990,7 +2031,7 @@ pub const Value = extern union {...@@ -1990,7 +2031,7 @@ pub const Value = extern union {
1990 for (a_field_vals) |a_elem, i| {2031 for (a_field_vals) |a_elem, i| {
1991 const b_elem = b_field_vals[i];2032 const b_elem = b_field_vals[i];
19922033
1993 if (!eql(a_elem, b_elem, elem_ty)) return false;2034 if (!eql(a_elem, b_elem, elem_ty, target)) return false;
1994 }2035 }
1995 return true;2036 return true;
1996 },2037 },
...@@ -2005,17 +2046,19 @@ pub const Value = extern union {...@@ -2005,17 +2046,19 @@ pub const Value = extern union {
2005 },2046 },
2006 .Auto => {2047 .Auto => {
2007 const tag_ty = ty.unionTagTypeHypothetical();2048 const tag_ty = ty.unionTagTypeHypothetical();
2008 if (!a_union.tag.eql(b_union.tag, tag_ty)) {2049 if (!a_union.tag.eql(b_union.tag, tag_ty, target)) {
2009 return false;2050 return false;
2010 }2051 }
2011 const active_field_ty = ty.unionFieldType(a_union.tag);2052 const active_field_ty = ty.unionFieldType(a_union.tag, target);
2012 return a_union.val.eql(b_union.val, active_field_ty);2053 return a_union.val.eql(b_union.val, active_field_ty, target);
2013 },2054 },
2014 }2055 }
2015 },2056 },
2016 else => {},2057 else => {},
2017 } else if (a_tag == .null_value or b_tag == .null_value) {2058 } else if (a_tag == .null_value or b_tag == .null_value) {
2018 return false;2059 return false;
2060 } else if (a_tag == .undef or b_tag == .undef) {
2061 return false;
2019 }2062 }
20202063
2021 if (a.pointerDecl()) |a_decl| {2064 if (a.pointerDecl()) |a_decl| {
...@@ -2034,7 +2077,7 @@ pub const Value = extern union {...@@ -2034,7 +2077,7 @@ pub const Value = extern union {
2034 var buf_b: ToTypeBuffer = undefined;2077 var buf_b: ToTypeBuffer = undefined;
2035 const a_type = a.toType(&buf_a);2078 const a_type = a.toType(&buf_a);
2036 const b_type = b.toType(&buf_b);2079 const b_type = b.toType(&buf_b);
2037 return a_type.eql(b_type);2080 return a_type.eql(b_type, target);
2038 },2081 },
2039 .Enum => {2082 .Enum => {
2040 var buf_a: Payload.U64 = undefined;2083 var buf_a: Payload.U64 = undefined;
...@@ -2043,7 +2086,7 @@ pub const Value = extern union {...@@ -2043,7 +2086,7 @@ pub const Value = extern union {
2043 const b_val = b.enumToInt(ty, &buf_b);2086 const b_val = b.enumToInt(ty, &buf_b);
2044 var buf_ty: Type.Payload.Bits = undefined;2087 var buf_ty: Type.Payload.Bits = undefined;
2045 const int_ty = ty.intTagType(&buf_ty);2088 const int_ty = ty.intTagType(&buf_ty);
2046 return eql(a_val, b_val, int_ty);2089 return eql(a_val, b_val, int_ty, target);
2047 },2090 },
2048 .Array, .Vector => {2091 .Array, .Vector => {
2049 const len = ty.arrayLen();2092 const len = ty.arrayLen();
...@@ -2054,7 +2097,7 @@ pub const Value = extern union {...@@ -2054,7 +2097,7 @@ pub const Value = extern union {
2054 while (i < len) : (i += 1) {2097 while (i < len) : (i += 1) {
2055 const a_elem = elemValueBuffer(a, i, &a_buf);2098 const a_elem = elemValueBuffer(a, i, &a_buf);
2056 const b_elem = elemValueBuffer(b, i, &b_buf);2099 const b_elem = elemValueBuffer(b, i, &b_buf);
2057 if (!eql(a_elem, b_elem, elem_ty)) return false;2100 if (!eql(a_elem, b_elem, elem_ty, target)) return false;
2058 }2101 }
2059 return true;2102 return true;
2060 },2103 },
...@@ -2070,15 +2113,15 @@ pub const Value = extern union {...@@ -2070,15 +2113,15 @@ pub const Value = extern union {
2070 if (a_nan or b_nan) {2113 if (a_nan or b_nan) {
2071 return a_nan and b_nan;2114 return a_nan and b_nan;
2072 }2115 }
2073 return order(a, b).compare(.eq);2116 return order(a, b, target).compare(.eq);
2074 },2117 },
2075 else => return order(a, b).compare(.eq),2118 else => return order(a, b, target).compare(.eq),
2076 }2119 }
2077 }2120 }
20782121
2079 /// This function is used by hash maps and so treats floating-point NaNs as equal2122 /// This function is used by hash maps and so treats floating-point NaNs as equal
2080 /// to each other, and not equal to other floating-point values.2123 /// to each other, and not equal to other floating-point values.
2081 pub fn hash(val: Value, ty: Type, hasher: *std.hash.Wyhash) void {2124 pub fn hash(val: Value, ty: Type, hasher: *std.hash.Wyhash, target: Target) void {
2082 const zig_ty_tag = ty.zigTypeTag();2125 const zig_ty_tag = ty.zigTypeTag();
2083 std.hash.autoHash(hasher, zig_ty_tag);2126 std.hash.autoHash(hasher, zig_ty_tag);
2084 if (val.isUndef()) return;2127 if (val.isUndef()) return;
...@@ -2095,7 +2138,7 @@ pub const Value = extern union {...@@ -2095,7 +2138,7 @@ pub const Value = extern union {
20952138
2096 .Type => {2139 .Type => {
2097 var buf: ToTypeBuffer = undefined;2140 var buf: ToTypeBuffer = undefined;
2098 return val.toType(&buf).hashWithHasher(hasher);2141 return val.toType(&buf).hashWithHasher(hasher, target);
2099 },2142 },
2100 .Float, .ComptimeFloat => {2143 .Float, .ComptimeFloat => {
2101 // Normalize the float here because this hash must match eql semantics.2144 // Normalize the float here because this hash must match eql semantics.
...@@ -2116,11 +2159,11 @@ pub const Value = extern union {...@@ -2116,11 +2159,11 @@ pub const Value = extern union {
2116 const slice = val.castTag(.slice).?.data;2159 const slice = val.castTag(.slice).?.data;
2117 var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;2160 var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;
2118 const ptr_ty = ty.slicePtrFieldType(&ptr_buf);2161 const ptr_ty = ty.slicePtrFieldType(&ptr_buf);
2119 hash(slice.ptr, ptr_ty, hasher);2162 hash(slice.ptr, ptr_ty, hasher, target);
2120 hash(slice.len, Type.usize, hasher);2163 hash(slice.len, Type.usize, hasher, target);
2121 },2164 },
21222165
2123 else => return hashPtr(val, hasher),2166 else => return hashPtr(val, hasher, target),
2124 },2167 },
2125 .Array, .Vector => {2168 .Array, .Vector => {
2126 const len = ty.arrayLen();2169 const len = ty.arrayLen();
...@@ -2129,14 +2172,14 @@ pub const Value = extern union {...@@ -2129,14 +2172,14 @@ pub const Value = extern union {
2129 var elem_value_buf: ElemValueBuffer = undefined;2172 var elem_value_buf: ElemValueBuffer = undefined;
2130 while (index < len) : (index += 1) {2173 while (index < len) : (index += 1) {
2131 const elem_val = val.elemValueBuffer(index, &elem_value_buf);2174 const elem_val = val.elemValueBuffer(index, &elem_value_buf);
2132 elem_val.hash(elem_ty, hasher);2175 elem_val.hash(elem_ty, hasher, target);
2133 }2176 }
2134 },2177 },
2135 .Struct => {2178 .Struct => {
2136 if (ty.isTupleOrAnonStruct()) {2179 if (ty.isTupleOrAnonStruct()) {
2137 const fields = ty.tupleFields();2180 const fields = ty.tupleFields();
2138 for (fields.values) |field_val, i| {2181 for (fields.values) |field_val, i| {
2139 field_val.hash(fields.types[i], hasher);2182 field_val.hash(fields.types[i], hasher, target);
2140 }2183 }
2141 return;2184 return;
2142 }2185 }
...@@ -2145,13 +2188,13 @@ pub const Value = extern union {...@@ -2145,13 +2188,13 @@ pub const Value = extern union {
2145 switch (val.tag()) {2188 switch (val.tag()) {
2146 .empty_struct_value => {2189 .empty_struct_value => {
2147 for (fields) |field| {2190 for (fields) |field| {
2148 field.default_val.hash(field.ty, hasher);2191 field.default_val.hash(field.ty, hasher, target);
2149 }2192 }
2150 },2193 },
2151 .aggregate => {2194 .aggregate => {
2152 const field_values = val.castTag(.aggregate).?.data;2195 const field_values = val.castTag(.aggregate).?.data;
2153 for (field_values) |field_val, i| {2196 for (field_values) |field_val, i| {
2154 field_val.hash(fields[i].ty, hasher);2197 field_val.hash(fields[i].ty, hasher, target);
2155 }2198 }
2156 },2199 },
2157 else => unreachable,2200 else => unreachable,
...@@ -2163,7 +2206,7 @@ pub const Value = extern union {...@@ -2163,7 +2206,7 @@ pub const Value = extern union {
2163 const sub_val = payload.data;2206 const sub_val = payload.data;
2164 var buffer: Type.Payload.ElemType = undefined;2207 var buffer: Type.Payload.ElemType = undefined;
2165 const sub_ty = ty.optionalChild(&buffer);2208 const sub_ty = ty.optionalChild(&buffer);
2166 sub_val.hash(sub_ty, hasher);2209 sub_val.hash(sub_ty, hasher, target);
2167 } else {2210 } else {
2168 std.hash.autoHash(hasher, false); // non-null2211 std.hash.autoHash(hasher, false); // non-null
2169 }2212 }
...@@ -2172,14 +2215,14 @@ pub const Value = extern union {...@@ -2172,14 +2215,14 @@ pub const Value = extern union {
2172 if (val.tag() == .@"error") {2215 if (val.tag() == .@"error") {
2173 std.hash.autoHash(hasher, false); // error2216 std.hash.autoHash(hasher, false); // error
2174 const sub_ty = ty.errorUnionSet();2217 const sub_ty = ty.errorUnionSet();
2175 val.hash(sub_ty, hasher);2218 val.hash(sub_ty, hasher, target);
2176 return;2219 return;
2177 }2220 }
21782221
2179 if (val.castTag(.eu_payload)) |payload| {2222 if (val.castTag(.eu_payload)) |payload| {
2180 std.hash.autoHash(hasher, true); // payload2223 std.hash.autoHash(hasher, true); // payload
2181 const sub_ty = ty.errorUnionPayload();2224 const sub_ty = ty.errorUnionPayload();
2182 payload.data.hash(sub_ty, hasher);2225 payload.data.hash(sub_ty, hasher, target);
2183 return;2226 return;
2184 } else unreachable;2227 } else unreachable;
2185 },2228 },
...@@ -2192,15 +2235,15 @@ pub const Value = extern union {...@@ -2192,15 +2235,15 @@ pub const Value = extern union {
2192 .Enum => {2235 .Enum => {
2193 var enum_space: Payload.U64 = undefined;2236 var enum_space: Payload.U64 = undefined;
2194 const int_val = val.enumToInt(ty, &enum_space);2237 const int_val = val.enumToInt(ty, &enum_space);
2195 hashInt(int_val, hasher);2238 hashInt(int_val, hasher, target);
2196 },2239 },
2197 .Union => {2240 .Union => {
2198 const union_obj = val.cast(Payload.Union).?.data;2241 const union_obj = val.cast(Payload.Union).?.data;
2199 if (ty.unionTagType()) |tag_ty| {2242 if (ty.unionTagType()) |tag_ty| {
2200 union_obj.tag.hash(tag_ty, hasher);2243 union_obj.tag.hash(tag_ty, hasher, target);
2201 }2244 }
2202 const active_field_ty = ty.unionFieldType(union_obj.tag);2245 const active_field_ty = ty.unionFieldType(union_obj.tag, target);
2203 union_obj.val.hash(active_field_ty, hasher);2246 union_obj.val.hash(active_field_ty, hasher, target);
2204 },2247 },
2205 .Fn => {2248 .Fn => {
2206 const func: *Module.Fn = val.castTag(.function).?.data;2249 const func: *Module.Fn = val.castTag(.function).?.data;
...@@ -2225,28 +2268,30 @@ pub const Value = extern union {...@@ -2225,28 +2268,30 @@ pub const Value = extern union {
22252268
2226 pub const ArrayHashContext = struct {2269 pub const ArrayHashContext = struct {
2227 ty: Type,2270 ty: Type,
2271 target: Target,
22282272
2229 pub fn hash(self: @This(), val: Value) u32 {2273 pub fn hash(self: @This(), val: Value) u32 {
2230 const other_context: HashContext = .{ .ty = self.ty };2274 const other_context: HashContext = .{ .ty = self.ty, .target = self.target };
2231 return @truncate(u32, other_context.hash(val));2275 return @truncate(u32, other_context.hash(val));
2232 }2276 }
2233 pub fn eql(self: @This(), a: Value, b: Value, b_index: usize) bool {2277 pub fn eql(self: @This(), a: Value, b: Value, b_index: usize) bool {
2234 _ = b_index;2278 _ = b_index;
2235 return a.eql(b, self.ty);2279 return a.eql(b, self.ty, self.target);
2236 }2280 }
2237 };2281 };
22382282
2239 pub const HashContext = struct {2283 pub const HashContext = struct {
2240 ty: Type,2284 ty: Type,
2285 target: Target,
22412286
2242 pub fn hash(self: @This(), val: Value) u64 {2287 pub fn hash(self: @This(), val: Value) u64 {
2243 var hasher = std.hash.Wyhash.init(0);2288 var hasher = std.hash.Wyhash.init(0);
2244 val.hash(self.ty, &hasher);2289 val.hash(self.ty, &hasher, self.target);
2245 return hasher.final();2290 return hasher.final();
2246 }2291 }
22472292
2248 pub fn eql(self: @This(), a: Value, b: Value) bool {2293 pub fn eql(self: @This(), a: Value, b: Value) bool {
2249 return a.eql(b, self.ty);2294 return a.eql(b, self.ty, self.target);
2250 }2295 }
2251 };2296 };
22522297
...@@ -2296,16 +2341,16 @@ pub const Value = extern union {...@@ -2296,16 +2341,16 @@ pub const Value = extern union {
2296 };2341 };
2297 }2342 }
22982343
2299 fn hashInt(int_val: Value, hasher: *std.hash.Wyhash) void {2344 fn hashInt(int_val: Value, hasher: *std.hash.Wyhash, target: Target) void {
2300 var buffer: BigIntSpace = undefined;2345 var buffer: BigIntSpace = undefined;
2301 const big = int_val.toBigInt(&buffer);2346 const big = int_val.toBigInt(&buffer, target);
2302 std.hash.autoHash(hasher, big.positive);2347 std.hash.autoHash(hasher, big.positive);
2303 for (big.limbs) |limb| {2348 for (big.limbs) |limb| {
2304 std.hash.autoHash(hasher, limb);2349 std.hash.autoHash(hasher, limb);
2305 }2350 }
2306 }2351 }
23072352
2308 fn hashPtr(ptr_val: Value, hasher: *std.hash.Wyhash) void {2353 fn hashPtr(ptr_val: Value, hasher: *std.hash.Wyhash, target: Target) void {
2309 switch (ptr_val.tag()) {2354 switch (ptr_val.tag()) {
2310 .decl_ref,2355 .decl_ref,
2311 .decl_ref_mut,2356 .decl_ref_mut,
...@@ -2319,25 +2364,25 @@ pub const Value = extern union {...@@ -2319,25 +2364,25 @@ pub const Value = extern union {
23192364
2320 .elem_ptr => {2365 .elem_ptr => {
2321 const elem_ptr = ptr_val.castTag(.elem_ptr).?.data;2366 const elem_ptr = ptr_val.castTag(.elem_ptr).?.data;
2322 hashPtr(elem_ptr.array_ptr, hasher);2367 hashPtr(elem_ptr.array_ptr, hasher, target);
2323 std.hash.autoHash(hasher, Value.Tag.elem_ptr);2368 std.hash.autoHash(hasher, Value.Tag.elem_ptr);
2324 std.hash.autoHash(hasher, elem_ptr.index);2369 std.hash.autoHash(hasher, elem_ptr.index);
2325 },2370 },
2326 .field_ptr => {2371 .field_ptr => {
2327 const field_ptr = ptr_val.castTag(.field_ptr).?.data;2372 const field_ptr = ptr_val.castTag(.field_ptr).?.data;
2328 std.hash.autoHash(hasher, Value.Tag.field_ptr);2373 std.hash.autoHash(hasher, Value.Tag.field_ptr);
2329 hashPtr(field_ptr.container_ptr, hasher);2374 hashPtr(field_ptr.container_ptr, hasher, target);
2330 std.hash.autoHash(hasher, field_ptr.field_index);2375 std.hash.autoHash(hasher, field_ptr.field_index);
2331 },2376 },
2332 .eu_payload_ptr => {2377 .eu_payload_ptr => {
2333 const err_union_ptr = ptr_val.castTag(.eu_payload_ptr).?.data;2378 const err_union_ptr = ptr_val.castTag(.eu_payload_ptr).?.data;
2334 std.hash.autoHash(hasher, Value.Tag.eu_payload_ptr);2379 std.hash.autoHash(hasher, Value.Tag.eu_payload_ptr);
2335 hashPtr(err_union_ptr.container_ptr, hasher);2380 hashPtr(err_union_ptr.container_ptr, hasher, target);
2336 },2381 },
2337 .opt_payload_ptr => {2382 .opt_payload_ptr => {
2338 const opt_ptr = ptr_val.castTag(.opt_payload_ptr).?.data;2383 const opt_ptr = ptr_val.castTag(.opt_payload_ptr).?.data;
2339 std.hash.autoHash(hasher, Value.Tag.opt_payload_ptr);2384 std.hash.autoHash(hasher, Value.Tag.opt_payload_ptr);
2340 hashPtr(opt_ptr.container_ptr, hasher);2385 hashPtr(opt_ptr.container_ptr, hasher, target);
2341 },2386 },
23422387
2343 .zero,2388 .zero,
...@@ -2349,7 +2394,7 @@ pub const Value = extern union {...@@ -2349,7 +2394,7 @@ pub const Value = extern union {
2349 .bool_false,2394 .bool_false,
2350 .bool_true,2395 .bool_true,
2351 .the_only_possible_value,2396 .the_only_possible_value,
2352 => return hashInt(ptr_val, hasher),2397 => return hashInt(ptr_val, hasher, target),
23532398
2354 else => unreachable,2399 else => unreachable,
2355 }2400 }
...@@ -2411,9 +2456,9 @@ pub const Value = extern union {...@@ -2411,9 +2456,9 @@ pub const Value = extern union {
2411 };2456 };
2412 }2457 }
24132458
2414 pub fn sliceLen(val: Value) u64 {2459 pub fn sliceLen(val: Value, target: Target) u64 {
2415 return switch (val.tag()) {2460 return switch (val.tag()) {
2416 .slice => val.castTag(.slice).?.data.len.toUnsignedInt(),2461 .slice => val.castTag(.slice).?.data.len.toUnsignedInt(target),
2417 .decl_ref => {2462 .decl_ref => {
2418 const decl = val.castTag(.decl_ref).?.data;2463 const decl = val.castTag(.decl_ref).?.data;
2419 if (decl.ty.zigTypeTag() == .Array) {2464 if (decl.ty.zigTypeTag() == .Array) {
...@@ -2561,7 +2606,7 @@ pub const Value = extern union {...@@ -2561,7 +2606,7 @@ pub const Value = extern union {
2561 }2606 }
25622607
2563 /// Returns a pointer to the element value at the index.2608 /// Returns a pointer to the element value at the index.
2564 pub fn elemPtr(val: Value, ty: Type, arena: Allocator, index: usize) Allocator.Error!Value {2609 pub fn elemPtr(val: Value, ty: Type, arena: Allocator, index: usize, target: Target) Allocator.Error!Value {
2565 const elem_ty = ty.elemType2();2610 const elem_ty = ty.elemType2();
2566 const ptr_val = switch (val.tag()) {2611 const ptr_val = switch (val.tag()) {
2567 .slice => val.castTag(.slice).?.data.ptr,2612 .slice => val.castTag(.slice).?.data.ptr,
...@@ -2570,7 +2615,7 @@ pub const Value = extern union {...@@ -2570,7 +2615,7 @@ pub const Value = extern union {
25702615
2571 if (ptr_val.tag() == .elem_ptr) {2616 if (ptr_val.tag() == .elem_ptr) {
2572 const elem_ptr = ptr_val.castTag(.elem_ptr).?.data;2617 const elem_ptr = ptr_val.castTag(.elem_ptr).?.data;
2573 if (elem_ptr.elem_ty.eql(elem_ty)) {2618 if (elem_ptr.elem_ty.eql(elem_ty, target)) {
2574 return Tag.elem_ptr.create(arena, .{2619 return Tag.elem_ptr.create(arena, .{
2575 .array_ptr = elem_ptr.array_ptr,2620 .array_ptr = elem_ptr.array_ptr,
2576 .elem_ty = elem_ptr.elem_ty,2621 .elem_ty = elem_ptr.elem_ty,
...@@ -2821,8 +2866,8 @@ pub const Value = extern union {...@@ -2821,8 +2866,8 @@ pub const Value = extern union {
28212866
2822 var lhs_space: Value.BigIntSpace = undefined;2867 var lhs_space: Value.BigIntSpace = undefined;
2823 var rhs_space: Value.BigIntSpace = undefined;2868 var rhs_space: Value.BigIntSpace = undefined;
2824 const lhs_bigint = lhs.toBigInt(&lhs_space);2869 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
2825 const rhs_bigint = rhs.toBigInt(&rhs_space);2870 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
2826 const limbs = try arena.alloc(2871 const limbs = try arena.alloc(
2827 std.math.big.Limb,2872 std.math.big.Limb,
2828 std.math.big.int.calcTwosCompLimbCount(info.bits),2873 std.math.big.int.calcTwosCompLimbCount(info.bits),
...@@ -2865,7 +2910,7 @@ pub const Value = extern union {...@@ -2865,7 +2910,7 @@ pub const Value = extern union {
2865 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);2910 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);
28662911
2867 if (ty.zigTypeTag() == .ComptimeInt) {2912 if (ty.zigTypeTag() == .ComptimeInt) {
2868 return intAdd(lhs, rhs, ty, arena);2913 return intAdd(lhs, rhs, ty, arena, target);
2869 }2914 }
28702915
2871 if (ty.isAnyFloat()) {2916 if (ty.isAnyFloat()) {
...@@ -2925,8 +2970,8 @@ pub const Value = extern union {...@@ -2925,8 +2970,8 @@ pub const Value = extern union {
29252970
2926 var lhs_space: Value.BigIntSpace = undefined;2971 var lhs_space: Value.BigIntSpace = undefined;
2927 var rhs_space: Value.BigIntSpace = undefined;2972 var rhs_space: Value.BigIntSpace = undefined;
2928 const lhs_bigint = lhs.toBigInt(&lhs_space);2973 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
2929 const rhs_bigint = rhs.toBigInt(&rhs_space);2974 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
2930 const limbs = try arena.alloc(2975 const limbs = try arena.alloc(
2931 std.math.big.Limb,2976 std.math.big.Limb,
2932 std.math.big.int.calcTwosCompLimbCount(info.bits),2977 std.math.big.int.calcTwosCompLimbCount(info.bits),
...@@ -2947,8 +2992,8 @@ pub const Value = extern union {...@@ -2947,8 +2992,8 @@ pub const Value = extern union {
29472992
2948 var lhs_space: Value.BigIntSpace = undefined;2993 var lhs_space: Value.BigIntSpace = undefined;
2949 var rhs_space: Value.BigIntSpace = undefined;2994 var rhs_space: Value.BigIntSpace = undefined;
2950 const lhs_bigint = lhs.toBigInt(&lhs_space);2995 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
2951 const rhs_bigint = rhs.toBigInt(&rhs_space);2996 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
2952 const limbs = try arena.alloc(2997 const limbs = try arena.alloc(
2953 std.math.big.Limb,2998 std.math.big.Limb,
2954 std.math.big.int.calcTwosCompLimbCount(info.bits),2999 std.math.big.int.calcTwosCompLimbCount(info.bits),
...@@ -2991,7 +3036,7 @@ pub const Value = extern union {...@@ -2991,7 +3036,7 @@ pub const Value = extern union {
2991 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);3036 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);
29923037
2993 if (ty.zigTypeTag() == .ComptimeInt) {3038 if (ty.zigTypeTag() == .ComptimeInt) {
2994 return intSub(lhs, rhs, ty, arena);3039 return intSub(lhs, rhs, ty, arena, target);
2995 }3040 }
29963041
2997 if (ty.isAnyFloat()) {3042 if (ty.isAnyFloat()) {
...@@ -3035,8 +3080,8 @@ pub const Value = extern union {...@@ -3035,8 +3080,8 @@ pub const Value = extern union {
30353080
3036 var lhs_space: Value.BigIntSpace = undefined;3081 var lhs_space: Value.BigIntSpace = undefined;
3037 var rhs_space: Value.BigIntSpace = undefined;3082 var rhs_space: Value.BigIntSpace = undefined;
3038 const lhs_bigint = lhs.toBigInt(&lhs_space);3083 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3039 const rhs_bigint = rhs.toBigInt(&rhs_space);3084 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
3040 const limbs = try arena.alloc(3085 const limbs = try arena.alloc(
3041 std.math.big.Limb,3086 std.math.big.Limb,
3042 std.math.big.int.calcTwosCompLimbCount(info.bits),3087 std.math.big.int.calcTwosCompLimbCount(info.bits),
...@@ -3057,8 +3102,8 @@ pub const Value = extern union {...@@ -3057,8 +3102,8 @@ pub const Value = extern union {
30573102
3058 var lhs_space: Value.BigIntSpace = undefined;3103 var lhs_space: Value.BigIntSpace = undefined;
3059 var rhs_space: Value.BigIntSpace = undefined;3104 var rhs_space: Value.BigIntSpace = undefined;
3060 const lhs_bigint = lhs.toBigInt(&lhs_space);3105 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3061 const rhs_bigint = rhs.toBigInt(&rhs_space);3106 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
3062 const limbs = try arena.alloc(3107 const limbs = try arena.alloc(
3063 std.math.big.Limb,3108 std.math.big.Limb,
3064 lhs_bigint.limbs.len + rhs_bigint.limbs.len,3109 lhs_bigint.limbs.len + rhs_bigint.limbs.len,
...@@ -3110,7 +3155,7 @@ pub const Value = extern union {...@@ -3110,7 +3155,7 @@ pub const Value = extern union {
3110 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);3155 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);
31113156
3112 if (ty.zigTypeTag() == .ComptimeInt) {3157 if (ty.zigTypeTag() == .ComptimeInt) {
3113 return intMul(lhs, rhs, ty, arena);3158 return intMul(lhs, rhs, ty, arena, target);
3114 }3159 }
31153160
3116 if (ty.isAnyFloat()) {3161 if (ty.isAnyFloat()) {
...@@ -3154,8 +3199,8 @@ pub const Value = extern union {...@@ -3154,8 +3199,8 @@ pub const Value = extern union {
31543199
3155 var lhs_space: Value.BigIntSpace = undefined;3200 var lhs_space: Value.BigIntSpace = undefined;
3156 var rhs_space: Value.BigIntSpace = undefined;3201 var rhs_space: Value.BigIntSpace = undefined;
3157 const lhs_bigint = lhs.toBigInt(&lhs_space);3202 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3158 const rhs_bigint = rhs.toBigInt(&rhs_space);3203 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
3159 const limbs = try arena.alloc(3204 const limbs = try arena.alloc(
3160 std.math.big.Limb,3205 std.math.big.Limb,
3161 std.math.max(3206 std.math.max(
...@@ -3175,24 +3220,24 @@ pub const Value = extern union {...@@ -3175,24 +3220,24 @@ pub const Value = extern union {
3175 }3220 }
31763221
3177 /// Supports both floats and ints; handles undefined.3222 /// Supports both floats and ints; handles undefined.
3178 pub fn numberMax(lhs: Value, rhs: Value) Value {3223 pub fn numberMax(lhs: Value, rhs: Value, target: Target) Value {
3179 if (lhs.isUndef() or rhs.isUndef()) return undef;3224 if (lhs.isUndef() or rhs.isUndef()) return undef;
3180 if (lhs.isNan()) return rhs;3225 if (lhs.isNan()) return rhs;
3181 if (rhs.isNan()) return lhs;3226 if (rhs.isNan()) return lhs;
31823227
3183 return switch (order(lhs, rhs)) {3228 return switch (order(lhs, rhs, target)) {
3184 .lt => rhs,3229 .lt => rhs,
3185 .gt, .eq => lhs,3230 .gt, .eq => lhs,
3186 };3231 };
3187 }3232 }
31883233
3189 /// Supports both floats and ints; handles undefined.3234 /// Supports both floats and ints; handles undefined.
3190 pub fn numberMin(lhs: Value, rhs: Value) Value {3235 pub fn numberMin(lhs: Value, rhs: Value, target: Target) Value {
3191 if (lhs.isUndef() or rhs.isUndef()) return undef;3236 if (lhs.isUndef() or rhs.isUndef()) return undef;
3192 if (lhs.isNan()) return rhs;3237 if (lhs.isNan()) return rhs;
3193 if (rhs.isNan()) return lhs;3238 if (rhs.isNan()) return lhs;
31943239
3195 return switch (order(lhs, rhs)) {3240 return switch (order(lhs, rhs, target)) {
3196 .lt => lhs,3241 .lt => lhs,
3197 .gt, .eq => rhs,3242 .gt, .eq => rhs,
3198 };3243 };
...@@ -3224,7 +3269,7 @@ pub const Value = extern union {...@@ -3224,7 +3269,7 @@ pub const Value = extern union {
3224 // TODO is this a performance issue? maybe we should try the operation without3269 // TODO is this a performance issue? maybe we should try the operation without
3225 // resorting to BigInt first.3270 // resorting to BigInt first.
3226 var val_space: Value.BigIntSpace = undefined;3271 var val_space: Value.BigIntSpace = undefined;
3227 const val_bigint = val.toBigInt(&val_space);3272 const val_bigint = val.toBigInt(&val_space, target);
3228 const limbs = try arena.alloc(3273 const limbs = try arena.alloc(
3229 std.math.big.Limb,3274 std.math.big.Limb,
3230 std.math.big.int.calcTwosCompLimbCount(info.bits),3275 std.math.big.int.calcTwosCompLimbCount(info.bits),
...@@ -3236,27 +3281,27 @@ pub const Value = extern union {...@@ -3236,27 +3281,27 @@ pub const Value = extern union {
3236 }3281 }
32373282
3238 /// operands must be (vectors of) integers; handles undefined scalars.3283 /// operands must be (vectors of) integers; handles undefined scalars.
3239 pub fn bitwiseAnd(lhs: Value, rhs: Value, ty: Type, allocator: Allocator) !Value {3284 pub fn bitwiseAnd(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, target: Target) !Value {
3240 if (ty.zigTypeTag() == .Vector) {3285 if (ty.zigTypeTag() == .Vector) {
3241 const result_data = try allocator.alloc(Value, ty.vectorLen());3286 const result_data = try allocator.alloc(Value, ty.vectorLen());
3242 for (result_data) |*scalar, i| {3287 for (result_data) |*scalar, i| {
3243 scalar.* = try bitwiseAndScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator);3288 scalar.* = try bitwiseAndScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator, target);
3244 }3289 }
3245 return Value.Tag.aggregate.create(allocator, result_data);3290 return Value.Tag.aggregate.create(allocator, result_data);
3246 }3291 }
3247 return bitwiseAndScalar(lhs, rhs, allocator);3292 return bitwiseAndScalar(lhs, rhs, allocator, target);
3248 }3293 }
32493294
3250 /// operands must be integers; handles undefined.3295 /// operands must be integers; handles undefined.
3251 pub fn bitwiseAndScalar(lhs: Value, rhs: Value, arena: Allocator) !Value {3296 pub fn bitwiseAndScalar(lhs: Value, rhs: Value, arena: Allocator, target: Target) !Value {
3252 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);3297 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);
32533298
3254 // TODO is this a performance issue? maybe we should try the operation without3299 // TODO is this a performance issue? maybe we should try the operation without
3255 // resorting to BigInt first.3300 // resorting to BigInt first.
3256 var lhs_space: Value.BigIntSpace = undefined;3301 var lhs_space: Value.BigIntSpace = undefined;
3257 var rhs_space: Value.BigIntSpace = undefined;3302 var rhs_space: Value.BigIntSpace = undefined;
3258 const lhs_bigint = lhs.toBigInt(&lhs_space);3303 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3259 const rhs_bigint = rhs.toBigInt(&rhs_space);3304 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
3260 const limbs = try arena.alloc(3305 const limbs = try arena.alloc(
3261 std.math.big.Limb,3306 std.math.big.Limb,
3262 // + 1 for negatives3307 // + 1 for negatives
...@@ -3283,38 +3328,38 @@ pub const Value = extern union {...@@ -3283,38 +3328,38 @@ pub const Value = extern union {
3283 pub fn bitwiseNandScalar(lhs: Value, rhs: Value, ty: Type, arena: Allocator, target: Target) !Value {3328 pub fn bitwiseNandScalar(lhs: Value, rhs: Value, ty: Type, arena: Allocator, target: Target) !Value {
3284 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);3329 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);
32853330
3286 const anded = try bitwiseAnd(lhs, rhs, ty, arena);3331 const anded = try bitwiseAnd(lhs, rhs, ty, arena, target);
32873332
3288 const all_ones = if (ty.isSignedInt())3333 const all_ones = if (ty.isSignedInt())
3289 try Value.Tag.int_i64.create(arena, -1)3334 try Value.Tag.int_i64.create(arena, -1)
3290 else3335 else
3291 try ty.maxInt(arena, target);3336 try ty.maxInt(arena, target);
32923337
3293 return bitwiseXor(anded, all_ones, ty, arena);3338 return bitwiseXor(anded, all_ones, ty, arena, target);
3294 }3339 }
32953340
3296 /// operands must be (vectors of) integers; handles undefined scalars.3341 /// operands must be (vectors of) integers; handles undefined scalars.
3297 pub fn bitwiseOr(lhs: Value, rhs: Value, ty: Type, allocator: Allocator) !Value {3342 pub fn bitwiseOr(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, target: Target) !Value {
3298 if (ty.zigTypeTag() == .Vector) {3343 if (ty.zigTypeTag() == .Vector) {
3299 const result_data = try allocator.alloc(Value, ty.vectorLen());3344 const result_data = try allocator.alloc(Value, ty.vectorLen());
3300 for (result_data) |*scalar, i| {3345 for (result_data) |*scalar, i| {
3301 scalar.* = try bitwiseOrScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator);3346 scalar.* = try bitwiseOrScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator, target);
3302 }3347 }
3303 return Value.Tag.aggregate.create(allocator, result_data);3348 return Value.Tag.aggregate.create(allocator, result_data);
3304 }3349 }
3305 return bitwiseOrScalar(lhs, rhs, allocator);3350 return bitwiseOrScalar(lhs, rhs, allocator, target);
3306 }3351 }
33073352
3308 /// operands must be integers; handles undefined.3353 /// operands must be integers; handles undefined.
3309 pub fn bitwiseOrScalar(lhs: Value, rhs: Value, arena: Allocator) !Value {3354 pub fn bitwiseOrScalar(lhs: Value, rhs: Value, arena: Allocator, target: Target) !Value {
3310 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);3355 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);
33113356
3312 // TODO is this a performance issue? maybe we should try the operation without3357 // TODO is this a performance issue? maybe we should try the operation without
3313 // resorting to BigInt first.3358 // resorting to BigInt first.
3314 var lhs_space: Value.BigIntSpace = undefined;3359 var lhs_space: Value.BigIntSpace = undefined;
3315 var rhs_space: Value.BigIntSpace = undefined;3360 var rhs_space: Value.BigIntSpace = undefined;
3316 const lhs_bigint = lhs.toBigInt(&lhs_space);3361 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3317 const rhs_bigint = rhs.toBigInt(&rhs_space);3362 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
3318 const limbs = try arena.alloc(3363 const limbs = try arena.alloc(
3319 std.math.big.Limb,3364 std.math.big.Limb,
3320 std.math.max(lhs_bigint.limbs.len, rhs_bigint.limbs.len),3365 std.math.max(lhs_bigint.limbs.len, rhs_bigint.limbs.len),
...@@ -3325,27 +3370,27 @@ pub const Value = extern union {...@@ -3325,27 +3370,27 @@ pub const Value = extern union {
3325 }3370 }
33263371
3327 /// operands must be (vectors of) integers; handles undefined scalars.3372 /// operands must be (vectors of) integers; handles undefined scalars.
3328 pub fn bitwiseXor(lhs: Value, rhs: Value, ty: Type, allocator: Allocator) !Value {3373 pub fn bitwiseXor(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, target: Target) !Value {
3329 if (ty.zigTypeTag() == .Vector) {3374 if (ty.zigTypeTag() == .Vector) {
3330 const result_data = try allocator.alloc(Value, ty.vectorLen());3375 const result_data = try allocator.alloc(Value, ty.vectorLen());
3331 for (result_data) |*scalar, i| {3376 for (result_data) |*scalar, i| {
3332 scalar.* = try bitwiseXorScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator);3377 scalar.* = try bitwiseXorScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator, target);
3333 }3378 }
3334 return Value.Tag.aggregate.create(allocator, result_data);3379 return Value.Tag.aggregate.create(allocator, result_data);
3335 }3380 }
3336 return bitwiseXorScalar(lhs, rhs, allocator);3381 return bitwiseXorScalar(lhs, rhs, allocator, target);
3337 }3382 }
33383383
3339 /// operands must be integers; handles undefined.3384 /// operands must be integers; handles undefined.
3340 pub fn bitwiseXorScalar(lhs: Value, rhs: Value, arena: Allocator) !Value {3385 pub fn bitwiseXorScalar(lhs: Value, rhs: Value, arena: Allocator, target: Target) !Value {
3341 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);3386 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);
33423387
3343 // TODO is this a performance issue? maybe we should try the operation without3388 // TODO is this a performance issue? maybe we should try the operation without
3344 // resorting to BigInt first.3389 // resorting to BigInt first.
3345 var lhs_space: Value.BigIntSpace = undefined;3390 var lhs_space: Value.BigIntSpace = undefined;
3346 var rhs_space: Value.BigIntSpace = undefined;3391 var rhs_space: Value.BigIntSpace = undefined;
3347 const lhs_bigint = lhs.toBigInt(&lhs_space);3392 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3348 const rhs_bigint = rhs.toBigInt(&rhs_space);3393 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
3349 const limbs = try arena.alloc(3394 const limbs = try arena.alloc(
3350 std.math.big.Limb,3395 std.math.big.Limb,
3351 // + 1 for negatives3396 // + 1 for negatives
...@@ -3356,24 +3401,24 @@ pub const Value = extern union {...@@ -3356,24 +3401,24 @@ pub const Value = extern union {
3356 return fromBigInt(arena, result_bigint.toConst());3401 return fromBigInt(arena, result_bigint.toConst());
3357 }3402 }
33583403
3359 pub fn intAdd(lhs: Value, rhs: Value, ty: Type, allocator: Allocator) !Value {3404 pub fn intAdd(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, target: Target) !Value {
3360 if (ty.zigTypeTag() == .Vector) {3405 if (ty.zigTypeTag() == .Vector) {
3361 const result_data = try allocator.alloc(Value, ty.vectorLen());3406 const result_data = try allocator.alloc(Value, ty.vectorLen());
3362 for (result_data) |*scalar, i| {3407 for (result_data) |*scalar, i| {
3363 scalar.* = try intAddScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator);3408 scalar.* = try intAddScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator, target);
3364 }3409 }
3365 return Value.Tag.aggregate.create(allocator, result_data);3410 return Value.Tag.aggregate.create(allocator, result_data);
3366 }3411 }
3367 return intAddScalar(lhs, rhs, allocator);3412 return intAddScalar(lhs, rhs, allocator, target);
3368 }3413 }
33693414
3370 pub fn intAddScalar(lhs: Value, rhs: Value, allocator: Allocator) !Value {3415 pub fn intAddScalar(lhs: Value, rhs: Value, allocator: Allocator, target: Target) !Value {
3371 // TODO is this a performance issue? maybe we should try the operation without3416 // TODO is this a performance issue? maybe we should try the operation without
3372 // resorting to BigInt first.3417 // resorting to BigInt first.
3373 var lhs_space: Value.BigIntSpace = undefined;3418 var lhs_space: Value.BigIntSpace = undefined;
3374 var rhs_space: Value.BigIntSpace = undefined;3419 var rhs_space: Value.BigIntSpace = undefined;
3375 const lhs_bigint = lhs.toBigInt(&lhs_space);3420 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3376 const rhs_bigint = rhs.toBigInt(&rhs_space);3421 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
3377 const limbs = try allocator.alloc(3422 const limbs = try allocator.alloc(
3378 std.math.big.Limb,3423 std.math.big.Limb,
3379 std.math.max(lhs_bigint.limbs.len, rhs_bigint.limbs.len) + 1,3424 std.math.max(lhs_bigint.limbs.len, rhs_bigint.limbs.len) + 1,
...@@ -3383,24 +3428,24 @@ pub const Value = extern union {...@@ -3383,24 +3428,24 @@ pub const Value = extern union {
3383 return fromBigInt(allocator, result_bigint.toConst());3428 return fromBigInt(allocator, result_bigint.toConst());
3384 }3429 }
33853430
3386 pub fn intSub(lhs: Value, rhs: Value, ty: Type, allocator: Allocator) !Value {3431 pub fn intSub(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, target: Target) !Value {
3387 if (ty.zigTypeTag() == .Vector) {3432 if (ty.zigTypeTag() == .Vector) {
3388 const result_data = try allocator.alloc(Value, ty.vectorLen());3433 const result_data = try allocator.alloc(Value, ty.vectorLen());
3389 for (result_data) |*scalar, i| {3434 for (result_data) |*scalar, i| {
3390 scalar.* = try intSubScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator);3435 scalar.* = try intSubScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator, target);
3391 }3436 }
3392 return Value.Tag.aggregate.create(allocator, result_data);3437 return Value.Tag.aggregate.create(allocator, result_data);
3393 }3438 }
3394 return intSubScalar(lhs, rhs, allocator);3439 return intSubScalar(lhs, rhs, allocator, target);
3395 }3440 }
33963441
3397 pub fn intSubScalar(lhs: Value, rhs: Value, allocator: Allocator) !Value {3442 pub fn intSubScalar(lhs: Value, rhs: Value, allocator: Allocator, target: Target) !Value {
3398 // TODO is this a performance issue? maybe we should try the operation without3443 // TODO is this a performance issue? maybe we should try the operation without
3399 // resorting to BigInt first.3444 // resorting to BigInt first.
3400 var lhs_space: Value.BigIntSpace = undefined;3445 var lhs_space: Value.BigIntSpace = undefined;
3401 var rhs_space: Value.BigIntSpace = undefined;3446 var rhs_space: Value.BigIntSpace = undefined;
3402 const lhs_bigint = lhs.toBigInt(&lhs_space);3447 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3403 const rhs_bigint = rhs.toBigInt(&rhs_space);3448 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
3404 const limbs = try allocator.alloc(3449 const limbs = try allocator.alloc(
3405 std.math.big.Limb,3450 std.math.big.Limb,
3406 std.math.max(lhs_bigint.limbs.len, rhs_bigint.limbs.len) + 1,3451 std.math.max(lhs_bigint.limbs.len, rhs_bigint.limbs.len) + 1,
...@@ -3410,24 +3455,24 @@ pub const Value = extern union {...@@ -3410,24 +3455,24 @@ pub const Value = extern union {
3410 return fromBigInt(allocator, result_bigint.toConst());3455 return fromBigInt(allocator, result_bigint.toConst());
3411 }3456 }
34123457
3413 pub fn intDiv(lhs: Value, rhs: Value, ty: Type, allocator: Allocator) !Value {3458 pub fn intDiv(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, target: Target) !Value {
3414 if (ty.zigTypeTag() == .Vector) {3459 if (ty.zigTypeTag() == .Vector) {
3415 const result_data = try allocator.alloc(Value, ty.vectorLen());3460 const result_data = try allocator.alloc(Value, ty.vectorLen());
3416 for (result_data) |*scalar, i| {3461 for (result_data) |*scalar, i| {
3417 scalar.* = try intDivScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator);3462 scalar.* = try intDivScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator, target);
3418 }3463 }
3419 return Value.Tag.aggregate.create(allocator, result_data);3464 return Value.Tag.aggregate.create(allocator, result_data);
3420 }3465 }
3421 return intDivScalar(lhs, rhs, allocator);3466 return intDivScalar(lhs, rhs, allocator, target);
3422 }3467 }
34233468
3424 pub fn intDivScalar(lhs: Value, rhs: Value, allocator: Allocator) !Value {3469 pub fn intDivScalar(lhs: Value, rhs: Value, allocator: Allocator, target: Target) !Value {
3425 // TODO is this a performance issue? maybe we should try the operation without3470 // TODO is this a performance issue? maybe we should try the operation without
3426 // resorting to BigInt first.3471 // resorting to BigInt first.
3427 var lhs_space: Value.BigIntSpace = undefined;3472 var lhs_space: Value.BigIntSpace = undefined;
3428 var rhs_space: Value.BigIntSpace = undefined;3473 var rhs_space: Value.BigIntSpace = undefined;
3429 const lhs_bigint = lhs.toBigInt(&lhs_space);3474 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3430 const rhs_bigint = rhs.toBigInt(&rhs_space);3475 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
3431 const limbs_q = try allocator.alloc(3476 const limbs_q = try allocator.alloc(
3432 std.math.big.Limb,3477 std.math.big.Limb,
3433 lhs_bigint.limbs.len,3478 lhs_bigint.limbs.len,
...@@ -3446,24 +3491,24 @@ pub const Value = extern union {...@@ -3446,24 +3491,24 @@ pub const Value = extern union {
3446 return fromBigInt(allocator, result_q.toConst());3491 return fromBigInt(allocator, result_q.toConst());
3447 }3492 }
34483493
3449 pub fn intDivFloor(lhs: Value, rhs: Value, ty: Type, allocator: Allocator) !Value {3494 pub fn intDivFloor(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, target: Target) !Value {
3450 if (ty.zigTypeTag() == .Vector) {3495 if (ty.zigTypeTag() == .Vector) {
3451 const result_data = try allocator.alloc(Value, ty.vectorLen());3496 const result_data = try allocator.alloc(Value, ty.vectorLen());
3452 for (result_data) |*scalar, i| {3497 for (result_data) |*scalar, i| {
3453 scalar.* = try intDivFloorScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator);3498 scalar.* = try intDivFloorScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator, target);
3454 }3499 }
3455 return Value.Tag.aggregate.create(allocator, result_data);3500 return Value.Tag.aggregate.create(allocator, result_data);
3456 }3501 }
3457 return intDivFloorScalar(lhs, rhs, allocator);3502 return intDivFloorScalar(lhs, rhs, allocator, target);
3458 }3503 }
34593504
3460 pub fn intDivFloorScalar(lhs: Value, rhs: Value, allocator: Allocator) !Value {3505 pub fn intDivFloorScalar(lhs: Value, rhs: Value, allocator: Allocator, target: Target) !Value {
3461 // TODO is this a performance issue? maybe we should try the operation without3506 // TODO is this a performance issue? maybe we should try the operation without
3462 // resorting to BigInt first.3507 // resorting to BigInt first.
3463 var lhs_space: Value.BigIntSpace = undefined;3508 var lhs_space: Value.BigIntSpace = undefined;
3464 var rhs_space: Value.BigIntSpace = undefined;3509 var rhs_space: Value.BigIntSpace = undefined;
3465 const lhs_bigint = lhs.toBigInt(&lhs_space);3510 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3466 const rhs_bigint = rhs.toBigInt(&rhs_space);3511 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
3467 const limbs_q = try allocator.alloc(3512 const limbs_q = try allocator.alloc(
3468 std.math.big.Limb,3513 std.math.big.Limb,
3469 lhs_bigint.limbs.len,3514 lhs_bigint.limbs.len,
...@@ -3482,24 +3527,24 @@ pub const Value = extern union {...@@ -3482,24 +3527,24 @@ pub const Value = extern union {
3482 return fromBigInt(allocator, result_q.toConst());3527 return fromBigInt(allocator, result_q.toConst());
3483 }3528 }
34843529
3485 pub fn intRem(lhs: Value, rhs: Value, ty: Type, allocator: Allocator) !Value {3530 pub fn intRem(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, target: Target) !Value {
3486 if (ty.zigTypeTag() == .Vector) {3531 if (ty.zigTypeTag() == .Vector) {
3487 const result_data = try allocator.alloc(Value, ty.vectorLen());3532 const result_data = try allocator.alloc(Value, ty.vectorLen());
3488 for (result_data) |*scalar, i| {3533 for (result_data) |*scalar, i| {
3489 scalar.* = try intRemScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator);3534 scalar.* = try intRemScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator, target);
3490 }3535 }
3491 return Value.Tag.aggregate.create(allocator, result_data);3536 return Value.Tag.aggregate.create(allocator, result_data);
3492 }3537 }
3493 return intRemScalar(lhs, rhs, allocator);3538 return intRemScalar(lhs, rhs, allocator, target);
3494 }3539 }
34953540
3496 pub fn intRemScalar(lhs: Value, rhs: Value, allocator: Allocator) !Value {3541 pub fn intRemScalar(lhs: Value, rhs: Value, allocator: Allocator, target: Target) !Value {
3497 // TODO is this a performance issue? maybe we should try the operation without3542 // TODO is this a performance issue? maybe we should try the operation without
3498 // resorting to BigInt first.3543 // resorting to BigInt first.
3499 var lhs_space: Value.BigIntSpace = undefined;3544 var lhs_space: Value.BigIntSpace = undefined;
3500 var rhs_space: Value.BigIntSpace = undefined;3545 var rhs_space: Value.BigIntSpace = undefined;
3501 const lhs_bigint = lhs.toBigInt(&lhs_space);3546 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3502 const rhs_bigint = rhs.toBigInt(&rhs_space);3547 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
3503 const limbs_q = try allocator.alloc(3548 const limbs_q = try allocator.alloc(
3504 std.math.big.Limb,3549 std.math.big.Limb,
3505 lhs_bigint.limbs.len,3550 lhs_bigint.limbs.len,
...@@ -3520,24 +3565,24 @@ pub const Value = extern union {...@@ -3520,24 +3565,24 @@ pub const Value = extern union {
3520 return fromBigInt(allocator, result_r.toConst());3565 return fromBigInt(allocator, result_r.toConst());
3521 }3566 }
35223567
3523 pub fn intMod(lhs: Value, rhs: Value, ty: Type, allocator: Allocator) !Value {3568 pub fn intMod(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, target: Target) !Value {
3524 if (ty.zigTypeTag() == .Vector) {3569 if (ty.zigTypeTag() == .Vector) {
3525 const result_data = try allocator.alloc(Value, ty.vectorLen());3570 const result_data = try allocator.alloc(Value, ty.vectorLen());
3526 for (result_data) |*scalar, i| {3571 for (result_data) |*scalar, i| {
3527 scalar.* = try intModScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator);3572 scalar.* = try intModScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator, target);
3528 }3573 }
3529 return Value.Tag.aggregate.create(allocator, result_data);3574 return Value.Tag.aggregate.create(allocator, result_data);
3530 }3575 }
3531 return intModScalar(lhs, rhs, allocator);3576 return intModScalar(lhs, rhs, allocator, target);
3532 }3577 }
35333578
3534 pub fn intModScalar(lhs: Value, rhs: Value, allocator: Allocator) !Value {3579 pub fn intModScalar(lhs: Value, rhs: Value, allocator: Allocator, target: Target) !Value {
3535 // TODO is this a performance issue? maybe we should try the operation without3580 // TODO is this a performance issue? maybe we should try the operation without
3536 // resorting to BigInt first.3581 // resorting to BigInt first.
3537 var lhs_space: Value.BigIntSpace = undefined;3582 var lhs_space: Value.BigIntSpace = undefined;
3538 var rhs_space: Value.BigIntSpace = undefined;3583 var rhs_space: Value.BigIntSpace = undefined;
3539 const lhs_bigint = lhs.toBigInt(&lhs_space);3584 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3540 const rhs_bigint = rhs.toBigInt(&rhs_space);3585 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
3541 const limbs_q = try allocator.alloc(3586 const limbs_q = try allocator.alloc(
3542 std.math.big.Limb,3587 std.math.big.Limb,
3543 lhs_bigint.limbs.len,3588 lhs_bigint.limbs.len,
...@@ -3658,24 +3703,24 @@ pub const Value = extern union {...@@ -3658,24 +3703,24 @@ pub const Value = extern union {
3658 }3703 }
3659 }3704 }
36603705
3661 pub fn intMul(lhs: Value, rhs: Value, ty: Type, allocator: Allocator) !Value {3706 pub fn intMul(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, target: Target) !Value {
3662 if (ty.zigTypeTag() == .Vector) {3707 if (ty.zigTypeTag() == .Vector) {
3663 const result_data = try allocator.alloc(Value, ty.vectorLen());3708 const result_data = try allocator.alloc(Value, ty.vectorLen());
3664 for (result_data) |*scalar, i| {3709 for (result_data) |*scalar, i| {
3665 scalar.* = try intMulScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator);3710 scalar.* = try intMulScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator, target);
3666 }3711 }
3667 return Value.Tag.aggregate.create(allocator, result_data);3712 return Value.Tag.aggregate.create(allocator, result_data);
3668 }3713 }
3669 return intMulScalar(lhs, rhs, allocator);3714 return intMulScalar(lhs, rhs, allocator, target);
3670 }3715 }
36713716
3672 pub fn intMulScalar(lhs: Value, rhs: Value, allocator: Allocator) !Value {3717 pub fn intMulScalar(lhs: Value, rhs: Value, allocator: Allocator, target: Target) !Value {
3673 // TODO is this a performance issue? maybe we should try the operation without3718 // TODO is this a performance issue? maybe we should try the operation without
3674 // resorting to BigInt first.3719 // resorting to BigInt first.
3675 var lhs_space: Value.BigIntSpace = undefined;3720 var lhs_space: Value.BigIntSpace = undefined;
3676 var rhs_space: Value.BigIntSpace = undefined;3721 var rhs_space: Value.BigIntSpace = undefined;
3677 const lhs_bigint = lhs.toBigInt(&lhs_space);3722 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3678 const rhs_bigint = rhs.toBigInt(&rhs_space);3723 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
3679 const limbs = try allocator.alloc(3724 const limbs = try allocator.alloc(
3680 std.math.big.Limb,3725 std.math.big.Limb,
3681 lhs_bigint.limbs.len + rhs_bigint.limbs.len,3726 lhs_bigint.limbs.len + rhs_bigint.limbs.len,
...@@ -3690,34 +3735,41 @@ pub const Value = extern union {...@@ -3690,34 +3735,41 @@ pub const Value = extern union {
3690 return fromBigInt(allocator, result_bigint.toConst());3735 return fromBigInt(allocator, result_bigint.toConst());
3691 }3736 }
36923737
3693 pub fn intTrunc(val: Value, ty: Type, allocator: Allocator, signedness: std.builtin.Signedness, bits: u16) !Value {3738 pub fn intTrunc(val: Value, ty: Type, allocator: Allocator, signedness: std.builtin.Signedness, bits: u16, target: Target) !Value {
3694 if (ty.zigTypeTag() == .Vector) {3739 if (ty.zigTypeTag() == .Vector) {
3695 const result_data = try allocator.alloc(Value, ty.vectorLen());3740 const result_data = try allocator.alloc(Value, ty.vectorLen());
3696 for (result_data) |*scalar, i| {3741 for (result_data) |*scalar, i| {
3697 scalar.* = try intTruncScalar(val.indexVectorlike(i), allocator, signedness, bits);3742 scalar.* = try intTruncScalar(val.indexVectorlike(i), allocator, signedness, bits, target);
3698 }3743 }
3699 return Value.Tag.aggregate.create(allocator, result_data);3744 return Value.Tag.aggregate.create(allocator, result_data);
3700 }3745 }
3701 return intTruncScalar(val, allocator, signedness, bits);3746 return intTruncScalar(val, allocator, signedness, bits, target);
3702 }3747 }
37033748
3704 /// This variant may vectorize on `bits`. Asserts that `bits` is a (vector of) `u16`.3749 /// This variant may vectorize on `bits`. Asserts that `bits` is a (vector of) `u16`.
3705 pub fn intTruncBitsAsValue(val: Value, ty: Type, allocator: Allocator, signedness: std.builtin.Signedness, bits: Value) !Value {3750 pub fn intTruncBitsAsValue(
3751 val: Value,
3752 ty: Type,
3753 allocator: Allocator,
3754 signedness: std.builtin.Signedness,
3755 bits: Value,
3756 target: Target,
3757 ) !Value {
3706 if (ty.zigTypeTag() == .Vector) {3758 if (ty.zigTypeTag() == .Vector) {
3707 const result_data = try allocator.alloc(Value, ty.vectorLen());3759 const result_data = try allocator.alloc(Value, ty.vectorLen());
3708 for (result_data) |*scalar, i| {3760 for (result_data) |*scalar, i| {
3709 scalar.* = try intTruncScalar(val.indexVectorlike(i), allocator, signedness, @intCast(u16, bits.indexVectorlike(i).toUnsignedInt()));3761 scalar.* = try intTruncScalar(val.indexVectorlike(i), allocator, signedness, @intCast(u16, bits.indexVectorlike(i).toUnsignedInt(target)), target);
3710 }3762 }
3711 return Value.Tag.aggregate.create(allocator, result_data);3763 return Value.Tag.aggregate.create(allocator, result_data);
3712 }3764 }
3713 return intTruncScalar(val, allocator, signedness, @intCast(u16, bits.toUnsignedInt()));3765 return intTruncScalar(val, allocator, signedness, @intCast(u16, bits.toUnsignedInt(target)), target);
3714 }3766 }
37153767
3716 pub fn intTruncScalar(val: Value, allocator: Allocator, signedness: std.builtin.Signedness, bits: u16) !Value {3768 pub fn intTruncScalar(val: Value, allocator: Allocator, signedness: std.builtin.Signedness, bits: u16, target: Target) !Value {
3717 if (bits == 0) return Value.zero;3769 if (bits == 0) return Value.zero;
37183770
3719 var val_space: Value.BigIntSpace = undefined;3771 var val_space: Value.BigIntSpace = undefined;
3720 const val_bigint = val.toBigInt(&val_space);3772 const val_bigint = val.toBigInt(&val_space, target);
37213773
3722 const limbs = try allocator.alloc(3774 const limbs = try allocator.alloc(
3723 std.math.big.Limb,3775 std.math.big.Limb,
...@@ -3729,23 +3781,23 @@ pub const Value = extern union {...@@ -3729,23 +3781,23 @@ pub const Value = extern union {
3729 return fromBigInt(allocator, result_bigint.toConst());3781 return fromBigInt(allocator, result_bigint.toConst());
3730 }3782 }
37313783
3732 pub fn shl(lhs: Value, rhs: Value, ty: Type, allocator: Allocator) !Value {3784 pub fn shl(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, target: Target) !Value {
3733 if (ty.zigTypeTag() == .Vector) {3785 if (ty.zigTypeTag() == .Vector) {
3734 const result_data = try allocator.alloc(Value, ty.vectorLen());3786 const result_data = try allocator.alloc(Value, ty.vectorLen());
3735 for (result_data) |*scalar, i| {3787 for (result_data) |*scalar, i| {
3736 scalar.* = try shlScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator);3788 scalar.* = try shlScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator, target);
3737 }3789 }
3738 return Value.Tag.aggregate.create(allocator, result_data);3790 return Value.Tag.aggregate.create(allocator, result_data);
3739 }3791 }
3740 return shlScalar(lhs, rhs, allocator);3792 return shlScalar(lhs, rhs, allocator, target);
3741 }3793 }
37423794
3743 pub fn shlScalar(lhs: Value, rhs: Value, allocator: Allocator) !Value {3795 pub fn shlScalar(lhs: Value, rhs: Value, allocator: Allocator, target: Target) !Value {
3744 // TODO is this a performance issue? maybe we should try the operation without3796 // TODO is this a performance issue? maybe we should try the operation without
3745 // resorting to BigInt first.3797 // resorting to BigInt first.
3746 var lhs_space: Value.BigIntSpace = undefined;3798 var lhs_space: Value.BigIntSpace = undefined;
3747 const lhs_bigint = lhs.toBigInt(&lhs_space);3799 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3748 const shift = @intCast(usize, rhs.toUnsignedInt());3800 const shift = @intCast(usize, rhs.toUnsignedInt(target));
3749 const limbs = try allocator.alloc(3801 const limbs = try allocator.alloc(
3750 std.math.big.Limb,3802 std.math.big.Limb,
3751 lhs_bigint.limbs.len + (shift / (@sizeOf(std.math.big.Limb) * 8)) + 1,3803 lhs_bigint.limbs.len + (shift / (@sizeOf(std.math.big.Limb) * 8)) + 1,
...@@ -3768,8 +3820,8 @@ pub const Value = extern union {...@@ -3768,8 +3820,8 @@ pub const Value = extern union {
3768 ) !OverflowArithmeticResult {3820 ) !OverflowArithmeticResult {
3769 const info = ty.intInfo(target);3821 const info = ty.intInfo(target);
3770 var lhs_space: Value.BigIntSpace = undefined;3822 var lhs_space: Value.BigIntSpace = undefined;
3771 const lhs_bigint = lhs.toBigInt(&lhs_space);3823 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3772 const shift = @intCast(usize, rhs.toUnsignedInt());3824 const shift = @intCast(usize, rhs.toUnsignedInt(target));
3773 const limbs = try allocator.alloc(3825 const limbs = try allocator.alloc(
3774 std.math.big.Limb,3826 std.math.big.Limb,
3775 lhs_bigint.limbs.len + (shift / (@sizeOf(std.math.big.Limb) * 8)) + 1,3827 lhs_bigint.limbs.len + (shift / (@sizeOf(std.math.big.Limb) * 8)) + 1,
...@@ -3819,8 +3871,8 @@ pub const Value = extern union {...@@ -3819,8 +3871,8 @@ pub const Value = extern union {
3819 const info = ty.intInfo(target);3871 const info = ty.intInfo(target);
38203872
3821 var lhs_space: Value.BigIntSpace = undefined;3873 var lhs_space: Value.BigIntSpace = undefined;
3822 const lhs_bigint = lhs.toBigInt(&lhs_space);3874 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3823 const shift = @intCast(usize, rhs.toUnsignedInt());3875 const shift = @intCast(usize, rhs.toUnsignedInt(target));
3824 const limbs = try arena.alloc(3876 const limbs = try arena.alloc(
3825 std.math.big.Limb,3877 std.math.big.Limb,
3826 std.math.big.int.calcTwosCompLimbCount(info.bits),3878 std.math.big.int.calcTwosCompLimbCount(info.bits),
...@@ -3858,29 +3910,29 @@ pub const Value = extern union {...@@ -3858,29 +3910,29 @@ pub const Value = extern union {
3858 arena: Allocator,3910 arena: Allocator,
3859 target: Target,3911 target: Target,
3860 ) !Value {3912 ) !Value {
3861 const shifted = try lhs.shl(rhs, ty, arena);3913 const shifted = try lhs.shl(rhs, ty, arena, target);
3862 const int_info = ty.intInfo(target);3914 const int_info = ty.intInfo(target);
3863 const truncated = try shifted.intTrunc(ty, arena, int_info.signedness, int_info.bits);3915 const truncated = try shifted.intTrunc(ty, arena, int_info.signedness, int_info.bits, target);
3864 return truncated;3916 return truncated;
3865 }3917 }
38663918
3867 pub fn shr(lhs: Value, rhs: Value, ty: Type, allocator: Allocator) !Value {3919 pub fn shr(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, target: Target) !Value {
3868 if (ty.zigTypeTag() == .Vector) {3920 if (ty.zigTypeTag() == .Vector) {
3869 const result_data = try allocator.alloc(Value, ty.vectorLen());3921 const result_data = try allocator.alloc(Value, ty.vectorLen());
3870 for (result_data) |*scalar, i| {3922 for (result_data) |*scalar, i| {
3871 scalar.* = try shrScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator);3923 scalar.* = try shrScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator, target);
3872 }3924 }
3873 return Value.Tag.aggregate.create(allocator, result_data);3925 return Value.Tag.aggregate.create(allocator, result_data);
3874 }3926 }
3875 return shrScalar(lhs, rhs, allocator);3927 return shrScalar(lhs, rhs, allocator, target);
3876 }3928 }
38773929
3878 pub fn shrScalar(lhs: Value, rhs: Value, allocator: Allocator) !Value {3930 pub fn shrScalar(lhs: Value, rhs: Value, allocator: Allocator, target: Target) !Value {
3879 // TODO is this a performance issue? maybe we should try the operation without3931 // TODO is this a performance issue? maybe we should try the operation without
3880 // resorting to BigInt first.3932 // resorting to BigInt first.
3881 var lhs_space: Value.BigIntSpace = undefined;3933 var lhs_space: Value.BigIntSpace = undefined;
3882 const lhs_bigint = lhs.toBigInt(&lhs_space);3934 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3883 const shift = @intCast(usize, rhs.toUnsignedInt());3935 const shift = @intCast(usize, rhs.toUnsignedInt(target));
38843936
3885 const result_limbs = lhs_bigint.limbs.len -| (shift / (@sizeOf(std.math.big.Limb) * 8));3937 const result_limbs = lhs_bigint.limbs.len -| (shift / (@sizeOf(std.math.big.Limb) * 8));
3886 if (result_limbs == 0) {3938 if (result_limbs == 0) {
test/behavior.zig+1-1
...@@ -125,6 +125,7 @@ test {...@@ -125,6 +125,7 @@ test {
125 _ = @import("behavior/src.zig");125 _ = @import("behavior/src.zig");
126 _ = @import("behavior/struct.zig");126 _ = @import("behavior/struct.zig");
127 _ = @import("behavior/struct_contains_null_ptr_itself.zig");127 _ = @import("behavior/struct_contains_null_ptr_itself.zig");
128 _ = @import("behavior/struct_contains_slice_of_itself.zig");
128 _ = @import("behavior/switch.zig");129 _ = @import("behavior/switch.zig");
129 _ = @import("behavior/switch_prong_err_enum.zig");130 _ = @import("behavior/switch_prong_err_enum.zig");
130 _ = @import("behavior/switch_prong_implicit_cast.zig");131 _ = @import("behavior/switch_prong_implicit_cast.zig");
...@@ -179,6 +180,5 @@ test {...@@ -179,6 +180,5 @@ test {
179 _ = @import("behavior/bugs/6781.zig");180 _ = @import("behavior/bugs/6781.zig");
180 _ = @import("behavior/bugs/7027.zig");181 _ = @import("behavior/bugs/7027.zig");
181 _ = @import("behavior/select.zig");182 _ = @import("behavior/select.zig");
182 _ = @import("behavior/struct_contains_slice_of_itself.zig");
183 }183 }
184}184}