authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-05-07 15:38:31-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-06-10 20:42:29-07:00
log4d88f825bc5eb14aa00446f046ab4714a4fdce70
tree4729946dff1e6ae200426418f4f6653003468d4f
parenta5fb16959423005de999fb541d5d5e9aebb8e09e

stage2: implement intTagType logic

This commit changes a lot of `*const Module` to `*Module` to make it work, since accessing the integer tag type of an enum might need to mutate the InternPool by adding a new integer type into it. An alternate strategy would be to pre-heat the InternPool with the integer tag type when creating an enum type, which would make it so that intTagType could accept a const Module instead of a mutable one, asserting that the InternPool already had the integer tag type.

19 files changed, 136 insertions(+), 137 deletions(-)

src/Module.zig+15-14
...@@ -944,7 +944,7 @@ pub const Decl = struct {...@@ -944,7 +944,7 @@ pub const Decl = struct {
944 };944 };
945 }945 }
946946
947 pub fn getAlignment(decl: Decl, mod: *const Module) u32 {947 pub fn getAlignment(decl: Decl, mod: *Module) u32 {
948 assert(decl.has_tv);948 assert(decl.has_tv);
949 if (decl.@"align" != 0) {949 if (decl.@"align" != 0) {
950 // Explicit alignment.950 // Explicit alignment.
...@@ -1053,7 +1053,7 @@ pub const Struct = struct {...@@ -1053,7 +1053,7 @@ pub const Struct = struct {
1053 /// Returns the field alignment. If the struct is packed, returns 0.1053 /// Returns the field alignment. If the struct is packed, returns 0.
1054 pub fn alignment(1054 pub fn alignment(
1055 field: Field,1055 field: Field,
1056 mod: *const Module,1056 mod: *Module,
1057 layout: std.builtin.Type.ContainerLayout,1057 layout: std.builtin.Type.ContainerLayout,
1058 ) u32 {1058 ) u32 {
1059 if (field.abi_align != 0) {1059 if (field.abi_align != 0) {
...@@ -1076,7 +1076,7 @@ pub const Struct = struct {...@@ -1076,7 +1076,7 @@ pub const Struct = struct {
1076 }1076 }
1077 }1077 }
10781078
1079 pub fn alignmentExtern(field: Field, mod: *const Module) u32 {1079 pub fn alignmentExtern(field: Field, mod: *Module) u32 {
1080 // This logic is duplicated in Type.abiAlignmentAdvanced.1080 // This logic is duplicated in Type.abiAlignmentAdvanced.
1081 const ty_abi_align = field.ty.abiAlignment(mod);1081 const ty_abi_align = field.ty.abiAlignment(mod);
10821082
...@@ -1157,7 +1157,7 @@ pub const Struct = struct {...@@ -1157,7 +1157,7 @@ pub const Struct = struct {
1157 };1157 };
1158 }1158 }
11591159
1160 pub fn packedFieldBitOffset(s: Struct, mod: *const Module, index: usize) u16 {1160 pub fn packedFieldBitOffset(s: Struct, mod: *Module, index: usize) u16 {
1161 assert(s.layout == .Packed);1161 assert(s.layout == .Packed);
1162 assert(s.haveLayout());1162 assert(s.haveLayout());
1163 var bit_sum: u64 = 0;1163 var bit_sum: u64 = 0;
...@@ -1171,7 +1171,7 @@ pub const Struct = struct {...@@ -1171,7 +1171,7 @@ pub const Struct = struct {
1171 }1171 }
11721172
1173 pub const RuntimeFieldIterator = struct {1173 pub const RuntimeFieldIterator = struct {
1174 module: *const Module,1174 module: *Module,
1175 struct_obj: *const Struct,1175 struct_obj: *const Struct,
1176 index: u32 = 0,1176 index: u32 = 0,
11771177
...@@ -1201,7 +1201,7 @@ pub const Struct = struct {...@@ -1201,7 +1201,7 @@ pub const Struct = struct {
1201 }1201 }
1202 };1202 };
12031203
1204 pub fn runtimeFieldIterator(s: *const Struct, module: *const Module) RuntimeFieldIterator {1204 pub fn runtimeFieldIterator(s: *const Struct, module: *Module) RuntimeFieldIterator {
1205 return .{1205 return .{
1206 .struct_obj = s,1206 .struct_obj = s,
1207 .module = module,1207 .module = module,
...@@ -1353,7 +1353,7 @@ pub const Union = struct {...@@ -1353,7 +1353,7 @@ pub const Union = struct {
1353 /// Returns the field alignment, assuming the union is not packed.1353 /// Returns the field alignment, assuming the union is not packed.
1354 /// Keep implementation in sync with `Sema.unionFieldAlignment`.1354 /// Keep implementation in sync with `Sema.unionFieldAlignment`.
1355 /// Prefer to call that function instead of this one during Sema.1355 /// Prefer to call that function instead of this one during Sema.
1356 pub fn normalAlignment(field: Field, mod: *const Module) u32 {1356 pub fn normalAlignment(field: Field, mod: *Module) u32 {
1357 if (field.abi_align == 0) {1357 if (field.abi_align == 0) {
1358 return field.ty.abiAlignment(mod);1358 return field.ty.abiAlignment(mod);
1359 } else {1359 } else {
...@@ -1413,7 +1413,7 @@ pub const Union = struct {...@@ -1413,7 +1413,7 @@ pub const Union = struct {
1413 };1413 };
1414 }1414 }
14151415
1416 pub fn hasAllZeroBitFieldTypes(u: Union, mod: *const Module) bool {1416 pub fn hasAllZeroBitFieldTypes(u: Union, mod: *Module) bool {
1417 assert(u.haveFieldTypes());1417 assert(u.haveFieldTypes());
1418 for (u.fields.values()) |field| {1418 for (u.fields.values()) |field| {
1419 if (field.ty.hasRuntimeBits(mod)) return false;1419 if (field.ty.hasRuntimeBits(mod)) return false;
...@@ -1421,7 +1421,7 @@ pub const Union = struct {...@@ -1421,7 +1421,7 @@ pub const Union = struct {
1421 return true;1421 return true;
1422 }1422 }
14231423
1424 pub fn mostAlignedField(u: Union, mod: *const Module) u32 {1424 pub fn mostAlignedField(u: Union, mod: *Module) u32 {
1425 assert(u.haveFieldTypes());1425 assert(u.haveFieldTypes());
1426 var most_alignment: u32 = 0;1426 var most_alignment: u32 = 0;
1427 var most_index: usize = undefined;1427 var most_index: usize = undefined;
...@@ -1438,7 +1438,7 @@ pub const Union = struct {...@@ -1438,7 +1438,7 @@ pub const Union = struct {
1438 }1438 }
14391439
1440 /// Returns 0 if the union is represented with 0 bits at runtime.1440 /// Returns 0 if the union is represented with 0 bits at runtime.
1441 pub fn abiAlignment(u: Union, mod: *const Module, have_tag: bool) u32 {1441 pub fn abiAlignment(u: Union, mod: *Module, have_tag: bool) u32 {
1442 var max_align: u32 = 0;1442 var max_align: u32 = 0;
1443 if (have_tag) max_align = u.tag_ty.abiAlignment(mod);1443 if (have_tag) max_align = u.tag_ty.abiAlignment(mod);
1444 for (u.fields.values()) |field| {1444 for (u.fields.values()) |field| {
...@@ -1450,7 +1450,7 @@ pub const Union = struct {...@@ -1450,7 +1450,7 @@ pub const Union = struct {
1450 return max_align;1450 return max_align;
1451 }1451 }
14521452
1453 pub fn abiSize(u: Union, mod: *const Module, have_tag: bool) u64 {1453 pub fn abiSize(u: Union, mod: *Module, have_tag: bool) u64 {
1454 return u.getLayout(mod, have_tag).abi_size;1454 return u.getLayout(mod, have_tag).abi_size;
1455 }1455 }
14561456
...@@ -1481,7 +1481,7 @@ pub const Union = struct {...@@ -1481,7 +1481,7 @@ pub const Union = struct {
1481 };1481 };
1482 }1482 }
14831483
1484 pub fn getLayout(u: Union, mod: *const Module, have_tag: bool) Layout {1484 pub fn getLayout(u: Union, mod: *Module, have_tag: bool) Layout {
1485 assert(u.haveLayout());1485 assert(u.haveLayout());
1486 var most_aligned_field: u32 = undefined;1486 var most_aligned_field: u32 = undefined;
1487 var most_aligned_field_size: u64 = undefined;1487 var most_aligned_field_size: u64 = undefined;
...@@ -6988,6 +6988,7 @@ pub const AtomicPtrAlignmentError = error{...@@ -6988,6 +6988,7 @@ pub const AtomicPtrAlignmentError = error{
6988 FloatTooBig,6988 FloatTooBig,
6989 IntTooBig,6989 IntTooBig,
6990 BadType,6990 BadType,
6991 OutOfMemory,
6991};6992};
69926993
6993pub const AtomicPtrAlignmentDiagnostics = struct {6994pub const AtomicPtrAlignmentDiagnostics = struct {
...@@ -7001,7 +7002,7 @@ pub const AtomicPtrAlignmentDiagnostics = struct {...@@ -7001,7 +7002,7 @@ pub const AtomicPtrAlignmentDiagnostics = struct {
7001// TODO this function does not take into account CPU features, which can affect7002// TODO this function does not take into account CPU features, which can affect
7002// this value. Audit this!7003// this value. Audit this!
7003pub fn atomicPtrAlignment(7004pub fn atomicPtrAlignment(
7004 mod: *const Module,7005 mod: *Module,
7005 ty: Type,7006 ty: Type,
7006 diags: *AtomicPtrAlignmentDiagnostics,7007 diags: *AtomicPtrAlignmentDiagnostics,
7007) AtomicPtrAlignmentError!u32 {7008) AtomicPtrAlignmentError!u32 {
...@@ -7080,7 +7081,7 @@ pub fn atomicPtrAlignment(...@@ -7080,7 +7081,7 @@ pub fn atomicPtrAlignment(
70807081
7081 const int_ty = switch (ty.zigTypeTag(mod)) {7082 const int_ty = switch (ty.zigTypeTag(mod)) {
7082 .Int => ty,7083 .Int => ty,
7083 .Enum => ty.intTagType(),7084 .Enum => try ty.intTagType(mod),
7084 .Float => {7085 .Float => {
7085 const bit_count = ty.floatBits(target);7086 const bit_count = ty.floatBits(target);
7086 if (bit_count > max_atomic_bits) {7087 if (bit_count > max_atomic_bits) {
src/Sema.zig+7-7
...@@ -8249,7 +8249,6 @@ fn zirEnumLiteral(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -8249,7 +8249,6 @@ fn zirEnumLiteral(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
82498249
8250fn zirEnumToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {8250fn zirEnumToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
8251 const mod = sema.mod;8251 const mod = sema.mod;
8252 const arena = sema.arena;
8253 const inst_data = sema.code.instructions.items(.data)[inst].un_node;8252 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
8254 const src = inst_data.src();8253 const src = inst_data.src();
8255 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };8254 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
...@@ -8278,7 +8277,7 @@ fn zirEnumToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -8278,7 +8277,7 @@ fn zirEnumToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
8278 };8277 };
8279 const enum_tag_ty = sema.typeOf(enum_tag);8278 const enum_tag_ty = sema.typeOf(enum_tag);
82808279
8281 const int_tag_ty = try enum_tag_ty.intTagType().copy(arena);8280 const int_tag_ty = try enum_tag_ty.intTagType(mod);
82828281
8283 if (try sema.typeHasOnePossibleValue(enum_tag_ty)) |opv| {8282 if (try sema.typeHasOnePossibleValue(enum_tag_ty)) |opv| {
8284 return sema.addConstant(int_tag_ty, opv);8283 return sema.addConstant(int_tag_ty, opv);
...@@ -8310,7 +8309,7 @@ fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -8310,7 +8309,7 @@ fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
83108309
8311 if (try sema.resolveMaybeUndefVal(operand)) |int_val| {8310 if (try sema.resolveMaybeUndefVal(operand)) |int_val| {
8312 if (dest_ty.isNonexhaustiveEnum()) {8311 if (dest_ty.isNonexhaustiveEnum()) {
8313 const int_tag_ty = dest_ty.intTagType();8312 const int_tag_ty = try dest_ty.intTagType(mod);
8314 if (try sema.intFitsInType(int_val, int_tag_ty, null)) {8313 if (try sema.intFitsInType(int_val, int_tag_ty, null)) {
8315 return sema.addConstant(dest_ty, int_val);8314 return sema.addConstant(dest_ty, int_val);
8316 }8315 }
...@@ -16268,7 +16267,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16268,7 +16267,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16268 },16267 },
16269 .Enum => {16268 .Enum => {
16270 // TODO: look into memoizing this result.16269 // TODO: look into memoizing this result.
16271 const int_tag_ty = try ty.intTagType().copy(sema.arena);16270 const int_tag_ty = try ty.intTagType(mod);
1627216271
16273 const is_exhaustive = Value.makeBool(!ty.isNonexhaustiveEnum());16272 const is_exhaustive = Value.makeBool(!ty.isNonexhaustiveEnum());
1627416273
...@@ -20354,7 +20353,7 @@ fn zirBitCount(...@@ -20354,7 +20353,7 @@ fn zirBitCount(
20354 block: *Block,20353 block: *Block,
20355 inst: Zir.Inst.Index,20354 inst: Zir.Inst.Index,
20356 air_tag: Air.Inst.Tag,20355 air_tag: Air.Inst.Tag,
20357 comptime comptimeOp: fn (val: Value, ty: Type, mod: *const Module) u64,20356 comptime comptimeOp: fn (val: Value, ty: Type, mod: *Module) u64,
20358) CompileError!Air.Inst.Ref {20357) CompileError!Air.Inst.Ref {
20359 const mod = sema.mod;20358 const mod = sema.mod;
20360 const inst_data = sema.code.instructions.items(.data)[inst].un_node;20359 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
...@@ -20755,6 +20754,7 @@ fn checkAtomicPtrOperand(...@@ -20755,6 +20754,7 @@ fn checkAtomicPtrOperand(
20755 const mod = sema.mod;20754 const mod = sema.mod;
20756 var diag: Module.AtomicPtrAlignmentDiagnostics = .{};20755 var diag: Module.AtomicPtrAlignmentDiagnostics = .{};
20757 const alignment = mod.atomicPtrAlignment(elem_ty, &diag) catch |err| switch (err) {20756 const alignment = mod.atomicPtrAlignment(elem_ty, &diag) catch |err| switch (err) {
20757 error.OutOfMemory => return error.OutOfMemory,
20758 error.FloatTooBig => return sema.fail(20758 error.FloatTooBig => return sema.fail(
20759 block,20759 block,
20760 elem_ty_src,20760 elem_ty_src,
...@@ -23462,7 +23462,7 @@ fn validateExternType(...@@ -23462,7 +23462,7 @@ fn validateExternType(
23462 return !Type.fnCallingConventionAllowsZigTypes(target, ty.fnCallingConvention());23462 return !Type.fnCallingConventionAllowsZigTypes(target, ty.fnCallingConvention());
23463 },23463 },
23464 .Enum => {23464 .Enum => {
23465 return sema.validateExternType(ty.intTagType(), position);23465 return sema.validateExternType(try ty.intTagType(mod), position);
23466 },23466 },
23467 .Struct, .Union => switch (ty.containerLayout()) {23467 .Struct, .Union => switch (ty.containerLayout()) {
23468 .Extern => return true,23468 .Extern => return true,
...@@ -23540,7 +23540,7 @@ fn explainWhyTypeIsNotExtern(...@@ -23540,7 +23540,7 @@ fn explainWhyTypeIsNotExtern(
23540 }23540 }
23541 },23541 },
23542 .Enum => {23542 .Enum => {
23543 const tag_ty = ty.intTagType();23543 const tag_ty = try ty.intTagType(mod);
23544 try mod.errNoteNonLazy(src_loc, msg, "enum tag type '{}' is not extern compatible", .{tag_ty.fmt(sema.mod)});23544 try mod.errNoteNonLazy(src_loc, msg, "enum tag type '{}' is not extern compatible", .{tag_ty.fmt(sema.mod)});
23545 try sema.explainWhyTypeIsNotExtern(msg, src_loc, tag_ty, position);23545 try sema.explainWhyTypeIsNotExtern(msg, src_loc, tag_ty, position);
23546 },23546 },
src/arch/aarch64/CodeGen.zig+1-1
...@@ -4533,7 +4533,7 @@ fn cmp(...@@ -4533,7 +4533,7 @@ fn cmp(
4533 }4533 }
4534 },4534 },
4535 .Float => return self.fail("TODO ARM cmp floats", .{}),4535 .Float => return self.fail("TODO ARM cmp floats", .{}),
4536 .Enum => lhs_ty.intTagType(),4536 .Enum => try lhs_ty.intTagType(mod),
4537 .Int => lhs_ty,4537 .Int => lhs_ty,
4538 .Bool => Type.u1,4538 .Bool => Type.u1,
4539 .Pointer => Type.usize,4539 .Pointer => Type.usize,
src/arch/aarch64/abi.zig+3-3
...@@ -15,7 +15,7 @@ pub const Class = union(enum) {...@@ -15,7 +15,7 @@ pub const Class = union(enum) {
15};15};
1616
17/// For `float_array` the second element will be the amount of floats.17/// For `float_array` the second element will be the amount of floats.
18pub fn classifyType(ty: Type, mod: *const Module) Class {18pub fn classifyType(ty: Type, mod: *Module) Class {
19 std.debug.assert(ty.hasRuntimeBitsIgnoreComptime(mod));19 std.debug.assert(ty.hasRuntimeBitsIgnoreComptime(mod));
2020
21 var maybe_float_bits: ?u16 = null;21 var maybe_float_bits: ?u16 = null;
...@@ -74,7 +74,7 @@ pub fn classifyType(ty: Type, mod: *const Module) Class {...@@ -74,7 +74,7 @@ pub fn classifyType(ty: Type, mod: *const Module) Class {
74}74}
7575
76const sret_float_count = 4;76const sret_float_count = 4;
77fn countFloats(ty: Type, mod: *const Module, maybe_float_bits: *?u16) u8 {77fn countFloats(ty: Type, mod: *Module, maybe_float_bits: *?u16) u8 {
78 const target = mod.getTarget();78 const target = mod.getTarget();
79 const invalid = std.math.maxInt(u8);79 const invalid = std.math.maxInt(u8);
80 switch (ty.zigTypeTag(mod)) {80 switch (ty.zigTypeTag(mod)) {
...@@ -115,7 +115,7 @@ fn countFloats(ty: Type, mod: *const Module, maybe_float_bits: *?u16) u8 {...@@ -115,7 +115,7 @@ fn countFloats(ty: Type, mod: *const Module, maybe_float_bits: *?u16) u8 {
115 }115 }
116}116}
117117
118pub fn getFloatArrayType(ty: Type, mod: *const Module) ?Type {118pub fn getFloatArrayType(ty: Type, mod: *Module) ?Type {
119 switch (ty.zigTypeTag(mod)) {119 switch (ty.zigTypeTag(mod)) {
120 .Union => {120 .Union => {
121 const fields = ty.unionFields();121 const fields = ty.unionFields();
src/arch/arm/CodeGen.zig+1-1
...@@ -4480,7 +4480,7 @@ fn cmp(...@@ -4480,7 +4480,7 @@ fn cmp(
4480 }4480 }
4481 },4481 },
4482 .Float => return self.fail("TODO ARM cmp floats", .{}),4482 .Float => return self.fail("TODO ARM cmp floats", .{}),
4483 .Enum => lhs_ty.intTagType(),4483 .Enum => try lhs_ty.intTagType(mod),
4484 .Int => lhs_ty,4484 .Int => lhs_ty,
4485 .Bool => Type.u1,4485 .Bool => Type.u1,
4486 .Pointer => Type.usize,4486 .Pointer => Type.usize,
src/arch/arm/abi.zig+2-2
...@@ -24,7 +24,7 @@ pub const Class = union(enum) {...@@ -24,7 +24,7 @@ pub const Class = union(enum) {
2424
25pub const Context = enum { ret, arg };25pub const Context = enum { ret, arg };
2626
27pub fn classifyType(ty: Type, mod: *const Module, ctx: Context) Class {27pub fn classifyType(ty: Type, mod: *Module, ctx: Context) Class {
28 assert(ty.hasRuntimeBitsIgnoreComptime(mod));28 assert(ty.hasRuntimeBitsIgnoreComptime(mod));
2929
30 var maybe_float_bits: ?u16 = null;30 var maybe_float_bits: ?u16 = null;
...@@ -116,7 +116,7 @@ pub fn classifyType(ty: Type, mod: *const Module, ctx: Context) Class {...@@ -116,7 +116,7 @@ pub fn classifyType(ty: Type, mod: *const Module, ctx: Context) Class {
116}116}
117117
118const byval_float_count = 4;118const byval_float_count = 4;
119fn countFloats(ty: Type, mod: *const Module, maybe_float_bits: *?u16) u32 {119fn countFloats(ty: Type, mod: *Module, maybe_float_bits: *?u16) u32 {
120 const target = mod.getTarget();120 const target = mod.getTarget();
121 const invalid = std.math.maxInt(u32);121 const invalid = std.math.maxInt(u32);
122 switch (ty.zigTypeTag(mod)) {122 switch (ty.zigTypeTag(mod)) {
src/arch/riscv64/abi.zig+1-1
...@@ -7,7 +7,7 @@ const Module = @import("../../Module.zig");...@@ -7,7 +7,7 @@ const Module = @import("../../Module.zig");
77
8pub const Class = enum { memory, byval, integer, double_integer };8pub const Class = enum { memory, byval, integer, double_integer };
99
10pub fn classifyType(ty: Type, mod: *const Module) Class {10pub fn classifyType(ty: Type, mod: *Module) Class {
11 const target = mod.getTarget();11 const target = mod.getTarget();
12 std.debug.assert(ty.hasRuntimeBitsIgnoreComptime(mod));12 std.debug.assert(ty.hasRuntimeBitsIgnoreComptime(mod));
1313
src/arch/sparc64/CodeGen.zig+1-1
...@@ -1436,7 +1436,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {...@@ -1436,7 +1436,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
14361436
1437 const int_ty = switch (lhs_ty.zigTypeTag(mod)) {1437 const int_ty = switch (lhs_ty.zigTypeTag(mod)) {
1438 .Vector => unreachable, // Handled by cmp_vector.1438 .Vector => unreachable, // Handled by cmp_vector.
1439 .Enum => lhs_ty.intTagType(),1439 .Enum => try lhs_ty.intTagType(mod),
1440 .Int => lhs_ty,1440 .Int => lhs_ty,
1441 .Bool => Type.u1,1441 .Bool => Type.u1,
1442 .Pointer => Type.usize,1442 .Pointer => Type.usize,
src/arch/wasm/CodeGen.zig+8-8
...@@ -1393,7 +1393,7 @@ fn resolveCallingConventionValues(func: *CodeGen, fn_ty: Type) InnerError!CallWV...@@ -1393,7 +1393,7 @@ fn resolveCallingConventionValues(func: *CodeGen, fn_ty: Type) InnerError!CallWV
1393 return result;1393 return result;
1394}1394}
13951395
1396fn firstParamSRet(cc: std.builtin.CallingConvention, return_type: Type, mod: *const Module) bool {1396fn firstParamSRet(cc: std.builtin.CallingConvention, return_type: Type, mod: *Module) bool {
1397 switch (cc) {1397 switch (cc) {
1398 .Unspecified, .Inline => return isByRef(return_type, mod),1398 .Unspecified, .Inline => return isByRef(return_type, mod),
1399 .C => {1399 .C => {
...@@ -1713,7 +1713,7 @@ fn arch(func: *const CodeGen) std.Target.Cpu.Arch {...@@ -1713,7 +1713,7 @@ fn arch(func: *const CodeGen) std.Target.Cpu.Arch {
17131713
1714/// For a given `Type`, will return true when the type will be passed1714/// For a given `Type`, will return true when the type will be passed
1715/// by reference, rather than by value1715/// by reference, rather than by value
1716fn isByRef(ty: Type, mod: *const Module) bool {1716fn isByRef(ty: Type, mod: *Module) bool {
1717 const target = mod.getTarget();1717 const target = mod.getTarget();
1718 switch (ty.zigTypeTag(mod)) {1718 switch (ty.zigTypeTag(mod)) {
1719 .Type,1719 .Type,
...@@ -1787,7 +1787,7 @@ const SimdStoreStrategy = enum {...@@ -1787,7 +1787,7 @@ const SimdStoreStrategy = enum {
1787/// This means when a given type is 128 bits and either the simd128 or relaxed-simd1787/// This means when a given type is 128 bits and either the simd128 or relaxed-simd
1788/// features are enabled, the function will return `.direct`. This would allow to store1788/// features are enabled, the function will return `.direct`. This would allow to store
1789/// it using a instruction, rather than an unrolled version.1789/// it using a instruction, rather than an unrolled version.
1790fn determineSimdStoreStrategy(ty: Type, mod: *const Module) SimdStoreStrategy {1790fn determineSimdStoreStrategy(ty: Type, mod: *Module) SimdStoreStrategy {
1791 std.debug.assert(ty.zigTypeTag(mod) == .Vector);1791 std.debug.assert(ty.zigTypeTag(mod) == .Vector);
1792 if (ty.bitSize(mod) != 128) return .unrolled;1792 if (ty.bitSize(mod) != 128) return .unrolled;
1793 const hasFeature = std.Target.wasm.featureSetHas;1793 const hasFeature = std.Target.wasm.featureSetHas;
...@@ -3121,7 +3121,7 @@ fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue {...@@ -3121,7 +3121,7 @@ fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue {
3121 else => return func.fail("TODO: lowerConstant for enum tag: {}", .{ty.tag()}),3121 else => return func.fail("TODO: lowerConstant for enum tag: {}", .{ty.tag()}),
3122 }3122 }
3123 } else {3123 } else {
3124 const int_tag_ty = ty.intTagType();3124 const int_tag_ty = try ty.intTagType(mod);
3125 return func.lowerConstant(val, int_tag_ty);3125 return func.lowerConstant(val, int_tag_ty);
3126 }3126 }
3127 },3127 },
...@@ -3235,7 +3235,7 @@ fn emitUndefined(func: *CodeGen, ty: Type) InnerError!WValue {...@@ -3235,7 +3235,7 @@ fn emitUndefined(func: *CodeGen, ty: Type) InnerError!WValue {
3235/// Returns a `Value` as a signed 32 bit value.3235/// Returns a `Value` as a signed 32 bit value.
3236/// It's illegal to provide a value with a type that cannot be represented3236/// It's illegal to provide a value with a type that cannot be represented
3237/// as an integer value.3237/// as an integer value.
3238fn valueAsI32(func: *const CodeGen, val: Value, ty: Type) i32 {3238fn valueAsI32(func: *const CodeGen, val: Value, ty: Type) !i32 {
3239 const mod = func.bin_file.base.options.module.?;3239 const mod = func.bin_file.base.options.module.?;
3240 switch (ty.zigTypeTag(mod)) {3240 switch (ty.zigTypeTag(mod)) {
3241 .Enum => {3241 .Enum => {
...@@ -3257,7 +3257,7 @@ fn valueAsI32(func: *const CodeGen, val: Value, ty: Type) i32 {...@@ -3257,7 +3257,7 @@ fn valueAsI32(func: *const CodeGen, val: Value, ty: Type) i32 {
3257 else => unreachable,3257 else => unreachable,
3258 }3258 }
3259 } else {3259 } else {
3260 const int_tag_ty = ty.intTagType();3260 const int_tag_ty = try ty.intTagType(mod);
3261 return func.valueAsI32(val, int_tag_ty);3261 return func.valueAsI32(val, int_tag_ty);
3262 }3262 }
3263 },3263 },
...@@ -3793,7 +3793,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -3793,7 +3793,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
37933793
3794 for (items, 0..) |ref, i| {3794 for (items, 0..) |ref, i| {
3795 const item_val = (try func.air.value(ref, mod)).?;3795 const item_val = (try func.air.value(ref, mod)).?;
3796 const int_val = func.valueAsI32(item_val, target_ty);3796 const int_val = try func.valueAsI32(item_val, target_ty);
3797 if (lowest_maybe == null or int_val < lowest_maybe.?) {3797 if (lowest_maybe == null or int_val < lowest_maybe.?) {
3798 lowest_maybe = int_val;3798 lowest_maybe = int_val;
3799 }3799 }
...@@ -6814,7 +6814,7 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {...@@ -6814,7 +6814,7 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {
6814 return loc.index;6814 return loc.index;
6815 }6815 }
68166816
6817 const int_tag_ty = enum_ty.intTagType();6817 const int_tag_ty = try enum_ty.intTagType(mod);
68186818
6819 if (int_tag_ty.bitSize(mod) > 64) {6819 if (int_tag_ty.bitSize(mod) > 64) {
6820 return func.fail("TODO: Implement @tagName for enums with tag size larger than 64 bits", .{});6820 return func.fail("TODO: Implement @tagName for enums with tag size larger than 64 bits", .{});
src/arch/wasm/abi.zig+2-2
...@@ -21,7 +21,7 @@ const direct: [2]Class = .{ .direct, .none };...@@ -21,7 +21,7 @@ const direct: [2]Class = .{ .direct, .none };
21/// Classifies a given Zig type to determine how they must be passed21/// Classifies a given Zig type to determine how they must be passed
22/// or returned as value within a wasm function.22/// or returned as value within a wasm function.
23/// When all elements result in `.none`, no value must be passed in or returned.23/// When all elements result in `.none`, no value must be passed in or returned.
24pub fn classifyType(ty: Type, mod: *const Module) [2]Class {24pub fn classifyType(ty: Type, mod: *Module) [2]Class {
25 const target = mod.getTarget();25 const target = mod.getTarget();
26 if (!ty.hasRuntimeBitsIgnoreComptime(mod)) return none;26 if (!ty.hasRuntimeBitsIgnoreComptime(mod)) return none;
27 switch (ty.zigTypeTag(mod)) {27 switch (ty.zigTypeTag(mod)) {
...@@ -93,7 +93,7 @@ pub fn classifyType(ty: Type, mod: *const Module) [2]Class {...@@ -93,7 +93,7 @@ pub fn classifyType(ty: Type, mod: *const Module) [2]Class {
93/// Returns the scalar type a given type can represent.93/// Returns the scalar type a given type can represent.
94/// Asserts given type can be represented as scalar, such as94/// Asserts given type can be represented as scalar, such as
95/// a struct with a single scalar field.95/// a struct with a single scalar field.
96pub fn scalarType(ty: Type, mod: *const Module) Type {96pub fn scalarType(ty: Type, mod: *Module) Type {
97 switch (ty.zigTypeTag(mod)) {97 switch (ty.zigTypeTag(mod)) {
98 .Struct => {98 .Struct => {
99 switch (ty.containerLayout()) {99 switch (ty.containerLayout()) {
src/arch/x86_64/CodeGen.zig+2-2
...@@ -605,7 +605,7 @@ const FrameAlloc = struct {...@@ -605,7 +605,7 @@ const FrameAlloc = struct {
605 .ref_count = 0,605 .ref_count = 0,
606 };606 };
607 }607 }
608 fn initType(ty: Type, mod: *const Module) FrameAlloc {608 fn initType(ty: Type, mod: *Module) FrameAlloc {
609 return init(.{ .size = ty.abiSize(mod), .alignment = ty.abiAlignment(mod) });609 return init(.{ .size = ty.abiSize(mod), .alignment = ty.abiAlignment(mod) });
610 }610 }
611};611};
...@@ -2309,7 +2309,7 @@ fn allocRegOrMemAdvanced(self: *Self, ty: Type, inst: ?Air.Inst.Index, reg_ok: b...@@ -2309,7 +2309,7 @@ fn allocRegOrMemAdvanced(self: *Self, ty: Type, inst: ?Air.Inst.Index, reg_ok: b
2309 return .{ .load_frame = .{ .index = frame_index } };2309 return .{ .load_frame = .{ .index = frame_index } };
2310}2310}
23112311
2312fn regClassForType(ty: Type, mod: *const Module) RegisterManager.RegisterBitSet {2312fn regClassForType(ty: Type, mod: *Module) RegisterManager.RegisterBitSet {
2313 return switch (ty.zigTypeTag(mod)) {2313 return switch (ty.zigTypeTag(mod)) {
2314 .Float, .Vector => sse,2314 .Float, .Vector => sse,
2315 else => gp,2315 else => gp,
src/arch/x86_64/abi.zig+2-2
...@@ -12,7 +12,7 @@ pub const Class = enum {...@@ -12,7 +12,7 @@ pub const Class = enum {
12 float_combine,12 float_combine,
13};13};
1414
15pub fn classifyWindows(ty: Type, mod: *const Module) Class {15pub fn classifyWindows(ty: Type, mod: *Module) Class {
16 // https://docs.microsoft.com/en-gb/cpp/build/x64-calling-convention?view=vs-201716 // https://docs.microsoft.com/en-gb/cpp/build/x64-calling-convention?view=vs-2017
17 // "There's a strict one-to-one correspondence between a function call's arguments17 // "There's a strict one-to-one correspondence between a function call's arguments
18 // and the registers used for those arguments. Any argument that doesn't fit in 818 // and the registers used for those arguments. Any argument that doesn't fit in 8
...@@ -68,7 +68,7 @@ pub const Context = enum { ret, arg, other };...@@ -68,7 +68,7 @@ pub const Context = enum { ret, arg, other };
6868
69/// There are a maximum of 8 possible return slots. Returned values are in69/// There are a maximum of 8 possible return slots. Returned values are in
70/// the beginning of the array; unused slots are filled with .none.70/// the beginning of the array; unused slots are filled with .none.
71pub fn classifySystemV(ty: Type, mod: *const Module, ctx: Context) [8]Class {71pub fn classifySystemV(ty: Type, mod: *Module, ctx: Context) [8]Class {
72 const target = mod.getTarget();72 const target = mod.getTarget();
73 const memory_class = [_]Class{73 const memory_class = [_]Class{
74 .memory, .none, .none, .none,74 .memory, .none, .none, .none,
src/codegen.zig+4-4
...@@ -1241,7 +1241,7 @@ pub fn genTypedValue(...@@ -1241,7 +1241,7 @@ pub fn genTypedValue(
1241 if (enum_values.count() != 0) {1241 if (enum_values.count() != 0) {
1242 const tag_val = enum_values.keys()[field_index.data];1242 const tag_val = enum_values.keys()[field_index.data];
1243 return genTypedValue(bin_file, src_loc, .{1243 return genTypedValue(bin_file, src_loc, .{
1244 .ty = typed_value.ty.intTagType(),1244 .ty = try typed_value.ty.intTagType(mod),
1245 .val = tag_val,1245 .val = tag_val,
1246 }, owner_decl_index);1246 }, owner_decl_index);
1247 } else {1247 } else {
...@@ -1251,7 +1251,7 @@ pub fn genTypedValue(...@@ -1251,7 +1251,7 @@ pub fn genTypedValue(
1251 else => unreachable,1251 else => unreachable,
1252 }1252 }
1253 } else {1253 } else {
1254 const int_tag_ty = typed_value.ty.intTagType();1254 const int_tag_ty = try typed_value.ty.intTagType(mod);
1255 return genTypedValue(bin_file, src_loc, .{1255 return genTypedValue(bin_file, src_loc, .{
1256 .ty = int_tag_ty,1256 .ty = int_tag_ty,
1257 .val = typed_value.val,1257 .val = typed_value.val,
...@@ -1303,7 +1303,7 @@ pub fn genTypedValue(...@@ -1303,7 +1303,7 @@ pub fn genTypedValue(
1303 return genUnnamedConst(bin_file, src_loc, typed_value, owner_decl_index);1303 return genUnnamedConst(bin_file, src_loc, typed_value, owner_decl_index);
1304}1304}
13051305
1306pub fn errUnionPayloadOffset(payload_ty: Type, mod: *const Module) u64 {1306pub fn errUnionPayloadOffset(payload_ty: Type, mod: *Module) u64 {
1307 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) return 0;1307 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) return 0;
1308 const payload_align = payload_ty.abiAlignment(mod);1308 const payload_align = payload_ty.abiAlignment(mod);
1309 const error_align = Type.anyerror.abiAlignment(mod);1309 const error_align = Type.anyerror.abiAlignment(mod);
...@@ -1314,7 +1314,7 @@ pub fn errUnionPayloadOffset(payload_ty: Type, mod: *const Module) u64 {...@@ -1314,7 +1314,7 @@ pub fn errUnionPayloadOffset(payload_ty: Type, mod: *const Module) u64 {
1314 }1314 }
1315}1315}
13161316
1317pub fn errUnionErrorOffset(payload_ty: Type, mod: *const Module) u64 {1317pub fn errUnionErrorOffset(payload_ty: Type, mod: *Module) u64 {
1318 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) return 0;1318 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) return 0;
1319 const payload_align = payload_ty.abiAlignment(mod);1319 const payload_align = payload_ty.abiAlignment(mod);
1320 const error_align = Type.anyerror.abiAlignment(mod);1320 const error_align = Type.anyerror.abiAlignment(mod);
src/codegen/c.zig+4-4
...@@ -1300,7 +1300,7 @@ pub const DeclGen = struct {...@@ -1300,7 +1300,7 @@ pub const DeclGen = struct {
1300 }1300 }
1301 },1301 },
1302 else => {1302 else => {
1303 const int_tag_ty = ty.intTagType();1303 const int_tag_ty = try ty.intTagType(mod);
1304 return dg.renderValue(writer, int_tag_ty, val, location);1304 return dg.renderValue(writer, int_tag_ty, val, location);
1305 },1305 },
1306 }1306 }
...@@ -5198,7 +5198,7 @@ fn fieldLocation(...@@ -5198,7 +5198,7 @@ fn fieldLocation(
5198 container_ty: Type,5198 container_ty: Type,
5199 field_ptr_ty: Type,5199 field_ptr_ty: Type,
5200 field_index: u32,5200 field_index: u32,
5201 mod: *const Module,5201 mod: *Module,
5202) union(enum) {5202) union(enum) {
5203 begin: void,5203 begin: void,
5204 field: CValue,5204 field: CValue,
...@@ -7722,7 +7722,7 @@ const LowerFnRetTyBuffer = struct {...@@ -7722,7 +7722,7 @@ const LowerFnRetTyBuffer = struct {
7722 values: [1]Value,7722 values: [1]Value,
7723 payload: Type.Payload.AnonStruct,7723 payload: Type.Payload.AnonStruct,
7724};7724};
7725fn lowerFnRetTy(ret_ty: Type, buffer: *LowerFnRetTyBuffer, mod: *const Module) Type {7725fn lowerFnRetTy(ret_ty: Type, buffer: *LowerFnRetTyBuffer, mod: *Module) Type {
7726 if (ret_ty.zigTypeTag(mod) == .NoReturn) return Type.noreturn;7726 if (ret_ty.zigTypeTag(mod) == .NoReturn) return Type.noreturn;
77277727
7728 if (lowersToArray(ret_ty, mod)) {7728 if (lowersToArray(ret_ty, mod)) {
...@@ -7740,7 +7740,7 @@ fn lowerFnRetTy(ret_ty: Type, buffer: *LowerFnRetTyBuffer, mod: *const Module) T...@@ -7740,7 +7740,7 @@ fn lowerFnRetTy(ret_ty: Type, buffer: *LowerFnRetTyBuffer, mod: *const Module) T
7740 return if (ret_ty.hasRuntimeBitsIgnoreComptime(mod)) ret_ty else Type.void;7740 return if (ret_ty.hasRuntimeBitsIgnoreComptime(mod)) ret_ty else Type.void;
7741}7741}
77427742
7743fn lowersToArray(ty: Type, mod: *const Module) bool {7743fn lowersToArray(ty: Type, mod: *Module) bool {
7744 return switch (ty.zigTypeTag(mod)) {7744 return switch (ty.zigTypeTag(mod)) {
7745 .Array, .Vector => return true,7745 .Array, .Vector => return true,
7746 else => return ty.isAbiInt(mod) and toCIntBits(@intCast(u32, ty.bitSize(mod))) == null,7746 else => return ty.isAbiInt(mod) and toCIntBits(@intCast(u32, ty.bitSize(mod))) == null,
src/codegen/c/type.zig+4-4
...@@ -292,17 +292,17 @@ pub const CType = extern union {...@@ -292,17 +292,17 @@ pub const CType = extern union {
292 .abi = std.math.log2_int(u32, abi_alignment),292 .abi = std.math.log2_int(u32, abi_alignment),
293 };293 };
294 }294 }
295 pub fn abiAlign(ty: Type, mod: *const Module) AlignAs {295 pub fn abiAlign(ty: Type, mod: *Module) AlignAs {
296 const abi_align = ty.abiAlignment(mod);296 const abi_align = ty.abiAlignment(mod);
297 return init(abi_align, abi_align);297 return init(abi_align, abi_align);
298 }298 }
299 pub fn fieldAlign(struct_ty: Type, field_i: usize, mod: *const Module) AlignAs {299 pub fn fieldAlign(struct_ty: Type, field_i: usize, mod: *Module) AlignAs {
300 return init(300 return init(
301 struct_ty.structFieldAlign(field_i, mod),301 struct_ty.structFieldAlign(field_i, mod),
302 struct_ty.structFieldType(field_i).abiAlignment(mod),302 struct_ty.structFieldType(field_i).abiAlignment(mod),
303 );303 );
304 }304 }
305 pub fn unionPayloadAlign(union_ty: Type, mod: *const Module) AlignAs {305 pub fn unionPayloadAlign(union_ty: Type, mod: *Module) AlignAs {
306 const union_obj = union_ty.cast(Type.Payload.Union).?.data;306 const union_obj = union_ty.cast(Type.Payload.Union).?.data;
307 const union_payload_align = union_obj.abiAlignment(mod, false);307 const union_payload_align = union_obj.abiAlignment(mod, false);
308 return init(union_payload_align, union_payload_align);308 return init(union_payload_align, union_payload_align);
...@@ -1897,7 +1897,7 @@ pub const CType = extern union {...@@ -1897,7 +1897,7 @@ pub const CType = extern union {
1897 }1897 }
1898 }1898 }
18991899
1900 fn createFromType(store: *Store.Promoted, ty: Type, mod: *const Module, kind: Kind) !CType {1900 fn createFromType(store: *Store.Promoted, ty: Type, mod: *Module, kind: Kind) !CType {
1901 var convert: Convert = undefined;1901 var convert: Convert = undefined;
1902 try convert.initType(ty, kind, .{ .imm = .{ .set = &store.set, .mod = mod } });1902 try convert.initType(ty, kind, .{ .imm = .{ .set = &store.set, .mod = mod } });
1903 return createFromConvert(store, ty, mod, kind, &convert);1903 return createFromConvert(store, ty, mod, kind, &convert);
src/codegen/llvm.zig+16-14
...@@ -1527,7 +1527,7 @@ pub const Object = struct {...@@ -1527,7 +1527,7 @@ pub const Object = struct {
1527 };1527 };
1528 const field_index_val = Value.initPayload(&buf_field_index.base);1528 const field_index_val = Value.initPayload(&buf_field_index.base);
15291529
1530 const int_ty = ty.intTagType();1530 const int_ty = try ty.intTagType(mod);
1531 const int_info = ty.intInfo(mod);1531 const int_info = ty.intInfo(mod);
1532 assert(int_info.bits != 0);1532 assert(int_info.bits != 0);
15331533
...@@ -2805,7 +2805,7 @@ pub const DeclGen = struct {...@@ -2805,7 +2805,7 @@ pub const DeclGen = struct {
2805 return dg.context.intType(info.bits);2805 return dg.context.intType(info.bits);
2806 },2806 },
2807 .Enum => {2807 .Enum => {
2808 const int_ty = t.intTagType();2808 const int_ty = try t.intTagType(mod);
2809 const bit_count = int_ty.intInfo(mod).bits;2809 const bit_count = int_ty.intInfo(mod).bits;
2810 assert(bit_count != 0);2810 assert(bit_count != 0);
2811 return dg.context.intType(bit_count);2811 return dg.context.intType(bit_count);
...@@ -4334,7 +4334,9 @@ pub const DeclGen = struct {...@@ -4334,7 +4334,9 @@ pub const DeclGen = struct {
4334 const mod = dg.module;4334 const mod = dg.module;
4335 const int_ty = switch (ty.zigTypeTag(mod)) {4335 const int_ty = switch (ty.zigTypeTag(mod)) {
4336 .Int => ty,4336 .Int => ty,
4337 .Enum => ty.intTagType(),4337 .Enum => ty.intTagType(mod) catch |err| switch (err) {
4338 error.OutOfMemory => @panic("OOM"),
4339 },
4338 .Float => {4340 .Float => {
4339 if (!is_rmw_xchg) return null;4341 if (!is_rmw_xchg) return null;
4340 return dg.context.intType(@intCast(c_uint, ty.abiSize(mod) * 8));4342 return dg.context.intType(@intCast(c_uint, ty.abiSize(mod) * 8));
...@@ -5286,7 +5288,7 @@ pub const FuncGen = struct {...@@ -5286,7 +5288,7 @@ pub const FuncGen = struct {
5286 const mod = self.dg.module;5288 const mod = self.dg.module;
5287 const scalar_ty = operand_ty.scalarType(mod);5289 const scalar_ty = operand_ty.scalarType(mod);
5288 const int_ty = switch (scalar_ty.zigTypeTag(mod)) {5290 const int_ty = switch (scalar_ty.zigTypeTag(mod)) {
5289 .Enum => scalar_ty.intTagType(),5291 .Enum => try scalar_ty.intTagType(mod),
5290 .Int, .Bool, .Pointer, .ErrorSet => scalar_ty,5292 .Int, .Bool, .Pointer, .ErrorSet => scalar_ty,
5291 .Optional => blk: {5293 .Optional => blk: {
5292 const payload_ty = operand_ty.optionalChild(mod);5294 const payload_ty = operand_ty.optionalChild(mod);
...@@ -8867,7 +8869,7 @@ pub const FuncGen = struct {...@@ -8867,7 +8869,7 @@ pub const FuncGen = struct {
8867 defer self.gpa.free(fqn);8869 defer self.gpa.free(fqn);
8868 const llvm_fn_name = try std.fmt.allocPrintZ(arena, "__zig_is_named_enum_value_{s}", .{fqn});8870 const llvm_fn_name = try std.fmt.allocPrintZ(arena, "__zig_is_named_enum_value_{s}", .{fqn});
88698871
8870 const int_tag_ty = enum_ty.intTagType();8872 const int_tag_ty = try enum_ty.intTagType(mod);
8871 const param_types = [_]*llvm.Type{try self.dg.lowerType(int_tag_ty)};8873 const param_types = [_]*llvm.Type{try self.dg.lowerType(int_tag_ty)};
88728874
8873 const llvm_ret_ty = try self.dg.lowerType(Type.bool);8875 const llvm_ret_ty = try self.dg.lowerType(Type.bool);
...@@ -8950,7 +8952,7 @@ pub const FuncGen = struct {...@@ -8950,7 +8952,7 @@ pub const FuncGen = struct {
8950 const usize_llvm_ty = try self.dg.lowerType(Type.usize);8952 const usize_llvm_ty = try self.dg.lowerType(Type.usize);
8951 const slice_alignment = slice_ty.abiAlignment(mod);8953 const slice_alignment = slice_ty.abiAlignment(mod);
89528954
8953 const int_tag_ty = enum_ty.intTagType();8955 const int_tag_ty = try enum_ty.intTagType(mod);
8954 const param_types = [_]*llvm.Type{try self.dg.lowerType(int_tag_ty)};8956 const param_types = [_]*llvm.Type{try self.dg.lowerType(int_tag_ty)};
89558957
8956 const fn_type = llvm.functionType(llvm_ret_ty, &param_types, param_types.len, .False);8958 const fn_type = llvm.functionType(llvm_ret_ty, &param_types, param_types.len, .False);
...@@ -10487,7 +10489,7 @@ fn toLlvmGlobalAddressSpace(wanted_address_space: std.builtin.AddressSpace, targ...@@ -10487,7 +10489,7 @@ fn toLlvmGlobalAddressSpace(wanted_address_space: std.builtin.AddressSpace, targ
10487fn llvmFieldIndex(10489fn llvmFieldIndex(
10488 ty: Type,10490 ty: Type,
10489 field_index: usize,10491 field_index: usize,
10490 mod: *const Module,10492 mod: *Module,
10491 ptr_pl_buf: *Type.Payload.Pointer,10493 ptr_pl_buf: *Type.Payload.Pointer,
10492) ?c_uint {10494) ?c_uint {
10493 // Detects where we inserted extra padding fields so that we can skip10495 // Detects where we inserted extra padding fields so that we can skip
...@@ -10564,7 +10566,7 @@ fn llvmFieldIndex(...@@ -10564,7 +10566,7 @@ fn llvmFieldIndex(
10564 }10566 }
10565}10567}
1056610568
10567fn firstParamSRet(fn_info: Type.Payload.Function.Data, mod: *const Module) bool {10569fn firstParamSRet(fn_info: Type.Payload.Function.Data, mod: *Module) bool {
10568 if (!fn_info.return_type.hasRuntimeBitsIgnoreComptime(mod)) return false;10570 if (!fn_info.return_type.hasRuntimeBitsIgnoreComptime(mod)) return false;
1056910571
10570 const target = mod.getTarget();10572 const target = mod.getTarget();
...@@ -10593,7 +10595,7 @@ fn firstParamSRet(fn_info: Type.Payload.Function.Data, mod: *const Module) bool...@@ -10593,7 +10595,7 @@ fn firstParamSRet(fn_info: Type.Payload.Function.Data, mod: *const Module) bool
10593 }10595 }
10594}10596}
1059510597
10596fn firstParamSRetSystemV(ty: Type, mod: *const Module) bool {10598fn firstParamSRetSystemV(ty: Type, mod: *Module) bool {
10597 const class = x86_64_abi.classifySystemV(ty, mod, .ret);10599 const class = x86_64_abi.classifySystemV(ty, mod, .ret);
10598 if (class[0] == .memory) return true;10600 if (class[0] == .memory) return true;
10599 if (class[0] == .x87 and class[2] != .none) return true;10601 if (class[0] == .x87 and class[2] != .none) return true;
...@@ -11041,7 +11043,7 @@ fn iterateParamTypes(dg: *DeclGen, fn_info: Type.Payload.Function.Data) ParamTyp...@@ -11041,7 +11043,7 @@ fn iterateParamTypes(dg: *DeclGen, fn_info: Type.Payload.Function.Data) ParamTyp
1104111043
11042fn ccAbiPromoteInt(11044fn ccAbiPromoteInt(
11043 cc: std.builtin.CallingConvention,11045 cc: std.builtin.CallingConvention,
11044 mod: *const Module,11046 mod: *Module,
11045 ty: Type,11047 ty: Type,
11046) ?std.builtin.Signedness {11048) ?std.builtin.Signedness {
11047 const target = mod.getTarget();11049 const target = mod.getTarget();
...@@ -11080,7 +11082,7 @@ fn ccAbiPromoteInt(...@@ -11080,7 +11082,7 @@ fn ccAbiPromoteInt(
1108011082
11081/// This is the one source of truth for whether a type is passed around as an LLVM pointer,11083/// This is the one source of truth for whether a type is passed around as an LLVM pointer,
11082/// or as an LLVM value.11084/// or as an LLVM value.
11083fn isByRef(ty: Type, mod: *const Module) bool {11085fn isByRef(ty: Type, mod: *Module) bool {
11084 // For tuples and structs, if there are more than this many non-void11086 // For tuples and structs, if there are more than this many non-void
11085 // fields, then we make it byref, otherwise byval.11087 // fields, then we make it byref, otherwise byval.
11086 const max_fields_byval = 0;11088 const max_fields_byval = 0;
...@@ -11159,7 +11161,7 @@ fn isByRef(ty: Type, mod: *const Module) bool {...@@ -11159,7 +11161,7 @@ fn isByRef(ty: Type, mod: *const Module) bool {
11159 }11161 }
11160}11162}
1116111163
11162fn isScalar(mod: *const Module, ty: Type) bool {11164fn isScalar(mod: *Module, ty: Type) bool {
11163 return switch (ty.zigTypeTag(mod)) {11165 return switch (ty.zigTypeTag(mod)) {
11164 .Void,11166 .Void,
11165 .Bool,11167 .Bool,
...@@ -11344,11 +11346,11 @@ fn buildAllocaInner(...@@ -11344,11 +11346,11 @@ fn buildAllocaInner(
11344 return alloca;11346 return alloca;
11345}11347}
1134611348
11347fn errUnionPayloadOffset(payload_ty: Type, mod: *const Module) u1 {11349fn errUnionPayloadOffset(payload_ty: Type, mod: *Module) u1 {
11348 return @boolToInt(Type.anyerror.abiAlignment(mod) > payload_ty.abiAlignment(mod));11350 return @boolToInt(Type.anyerror.abiAlignment(mod) > payload_ty.abiAlignment(mod));
11349}11351}
1135011352
11351fn errUnionErrorOffset(payload_ty: Type, mod: *const Module) u1 {11353fn errUnionErrorOffset(payload_ty: Type, mod: *Module) u1 {
11352 return @boolToInt(Type.anyerror.abiAlignment(mod) <= payload_ty.abiAlignment(mod));11354 return @boolToInt(Type.anyerror.abiAlignment(mod) <= payload_ty.abiAlignment(mod));
11353}11355}
1135411356
src/codegen/spirv.zig+3-3
...@@ -745,7 +745,7 @@ pub const DeclGen = struct {...@@ -745,7 +745,7 @@ pub const DeclGen = struct {
745 .Enum => {745 .Enum => {
746 const int_val = try val.enumToInt(ty, mod);746 const int_val = try val.enumToInt(ty, mod);
747747
748 const int_ty = ty.intTagType();748 const int_ty = try ty.intTagType(mod);
749749
750 try self.lower(int_ty, int_val);750 try self.lower(int_ty, int_val);
751 },751 },
...@@ -1195,7 +1195,7 @@ pub const DeclGen = struct {...@@ -1195,7 +1195,7 @@ pub const DeclGen = struct {
1195 return try self.intType(int_info.signedness, int_info.bits);1195 return try self.intType(int_info.signedness, int_info.bits);
1196 },1196 },
1197 .Enum => {1197 .Enum => {
1198 const tag_ty = ty.intTagType();1198 const tag_ty = try ty.intTagType(mod);
1199 return self.resolveType(tag_ty, repr);1199 return self.resolveType(tag_ty, repr);
1200 },1200 },
1201 .Float => {1201 .Float => {
...@@ -3090,7 +3090,7 @@ pub const DeclGen = struct {...@@ -3090,7 +3090,7 @@ pub const DeclGen = struct {
3090 break :blk if (backing_bits <= 32) @as(u32, 1) else 2;3090 break :blk if (backing_bits <= 32) @as(u32, 1) else 2;
3091 },3091 },
3092 .Enum => blk: {3092 .Enum => blk: {
3093 const int_ty = cond_ty.intTagType();3093 const int_ty = try cond_ty.intTagType(mod);
3094 const int_info = int_ty.intInfo(mod);3094 const int_info = int_ty.intInfo(mod);
3095 const backing_bits = self.backingIntBits(int_info.bits) orelse {3095 const backing_bits = self.backingIntBits(int_info.bits) orelse {
3096 return self.todo("implement composite int switch", .{});3096 return self.todo("implement composite int switch", .{});
src/type.zig+37-43
...@@ -1606,7 +1606,7 @@ pub const Type = struct {...@@ -1606,7 +1606,7 @@ pub const Type = struct {
1606 /// may return false positives.1606 /// may return false positives.
1607 pub fn hasRuntimeBitsAdvanced(1607 pub fn hasRuntimeBitsAdvanced(
1608 ty: Type,1608 ty: Type,
1609 mod: *const Module,1609 mod: *Module,
1610 ignore_comptime_only: bool,1610 ignore_comptime_only: bool,
1611 strat: AbiAlignmentAdvancedStrat,1611 strat: AbiAlignmentAdvancedStrat,
1612 ) RuntimeBitsError!bool {1612 ) RuntimeBitsError!bool {
...@@ -1785,7 +1785,7 @@ pub const Type = struct {...@@ -1785,7 +1785,7 @@ pub const Type = struct {
1785 return enum_simple.fields.count() >= 2;1785 return enum_simple.fields.count() >= 2;
1786 },1786 },
1787 .enum_numbered, .enum_nonexhaustive => {1787 .enum_numbered, .enum_nonexhaustive => {
1788 const int_tag_ty = ty.intTagType();1788 const int_tag_ty = try ty.intTagType(mod);
1789 return int_tag_ty.hasRuntimeBitsAdvanced(mod, ignore_comptime_only, strat);1789 return int_tag_ty.hasRuntimeBitsAdvanced(mod, ignore_comptime_only, strat);
1790 },1790 },
17911791
...@@ -1850,7 +1850,7 @@ pub const Type = struct {...@@ -1850,7 +1850,7 @@ pub const Type = struct {
1850 /// true if and only if the type has a well-defined memory layout1850 /// true if and only if the type has a well-defined memory layout
1851 /// readFrom/writeToMemory are supported only for types with a well-1851 /// readFrom/writeToMemory are supported only for types with a well-
1852 /// defined memory layout1852 /// defined memory layout
1853 pub fn hasWellDefinedLayout(ty: Type, mod: *const Module) bool {1853 pub fn hasWellDefinedLayout(ty: Type, mod: *Module) bool {
1854 if (ty.ip_index != .none) return switch (mod.intern_pool.indexToKey(ty.ip_index)) {1854 if (ty.ip_index != .none) return switch (mod.intern_pool.indexToKey(ty.ip_index)) {
1855 .int_type => true,1855 .int_type => true,
1856 .ptr_type => true,1856 .ptr_type => true,
...@@ -1952,15 +1952,15 @@ pub const Type = struct {...@@ -1952,15 +1952,15 @@ pub const Type = struct {
1952 };1952 };
1953 }1953 }
19541954
1955 pub fn hasRuntimeBits(ty: Type, mod: *const Module) bool {1955 pub fn hasRuntimeBits(ty: Type, mod: *Module) bool {
1956 return hasRuntimeBitsAdvanced(ty, mod, false, .eager) catch unreachable;1956 return hasRuntimeBitsAdvanced(ty, mod, false, .eager) catch unreachable;
1957 }1957 }
19581958
1959 pub fn hasRuntimeBitsIgnoreComptime(ty: Type, mod: *const Module) bool {1959 pub fn hasRuntimeBitsIgnoreComptime(ty: Type, mod: *Module) bool {
1960 return hasRuntimeBitsAdvanced(ty, mod, true, .eager) catch unreachable;1960 return hasRuntimeBitsAdvanced(ty, mod, true, .eager) catch unreachable;
1961 }1961 }
19621962
1963 pub fn isFnOrHasRuntimeBits(ty: Type, mod: *const Module) bool {1963 pub fn isFnOrHasRuntimeBits(ty: Type, mod: *Module) bool {
1964 switch (ty.zigTypeTag(mod)) {1964 switch (ty.zigTypeTag(mod)) {
1965 .Fn => {1965 .Fn => {
1966 const fn_info = ty.fnInfo();1966 const fn_info = ty.fnInfo();
...@@ -1980,7 +1980,7 @@ pub const Type = struct {...@@ -1980,7 +1980,7 @@ pub const Type = struct {
1980 }1980 }
19811981
1982 /// Same as `isFnOrHasRuntimeBits` but comptime-only types may return a false positive.1982 /// Same as `isFnOrHasRuntimeBits` but comptime-only types may return a false positive.
1983 pub fn isFnOrHasRuntimeBitsIgnoreComptime(ty: Type, mod: *const Module) bool {1983 pub fn isFnOrHasRuntimeBitsIgnoreComptime(ty: Type, mod: *Module) bool {
1984 return switch (ty.zigTypeTag(mod)) {1984 return switch (ty.zigTypeTag(mod)) {
1985 .Fn => true,1985 .Fn => true,
1986 else => return ty.hasRuntimeBitsIgnoreComptime(mod),1986 else => return ty.hasRuntimeBitsIgnoreComptime(mod),
...@@ -2019,11 +2019,11 @@ pub const Type = struct {...@@ -2019,11 +2019,11 @@ pub const Type = struct {
2019 }2019 }
20202020
2021 /// Returns 0 if the pointer is naturally aligned and the element type is 0-bit.2021 /// Returns 0 if the pointer is naturally aligned and the element type is 0-bit.
2022 pub fn ptrAlignment(ty: Type, mod: *const Module) u32 {2022 pub fn ptrAlignment(ty: Type, mod: *Module) u32 {
2023 return ptrAlignmentAdvanced(ty, mod, null) catch unreachable;2023 return ptrAlignmentAdvanced(ty, mod, null) catch unreachable;
2024 }2024 }
20252025
2026 pub fn ptrAlignmentAdvanced(ty: Type, mod: *const Module, opt_sema: ?*Sema) !u32 {2026 pub fn ptrAlignmentAdvanced(ty: Type, mod: *Module, opt_sema: ?*Sema) !u32 {
2027 switch (ty.ip_index) {2027 switch (ty.ip_index) {
2028 .none => switch (ty.tag()) {2028 .none => switch (ty.tag()) {
2029 .pointer => {2029 .pointer => {
...@@ -2072,7 +2072,7 @@ pub const Type = struct {...@@ -2072,7 +2072,7 @@ pub const Type = struct {
2072 }2072 }
20732073
2074 /// Returns 0 for 0-bit types.2074 /// Returns 0 for 0-bit types.
2075 pub fn abiAlignment(ty: Type, mod: *const Module) u32 {2075 pub fn abiAlignment(ty: Type, mod: *Module) u32 {
2076 return (ty.abiAlignmentAdvanced(mod, .eager) catch unreachable).scalar;2076 return (ty.abiAlignmentAdvanced(mod, .eager) catch unreachable).scalar;
2077 }2077 }
20782078
...@@ -2103,7 +2103,7 @@ pub const Type = struct {...@@ -2103,7 +2103,7 @@ pub const Type = struct {
2103 /// necessary, possibly returning a CompileError.2103 /// necessary, possibly returning a CompileError.
2104 pub fn abiAlignmentAdvanced(2104 pub fn abiAlignmentAdvanced(
2105 ty: Type,2105 ty: Type,
2106 mod: *const Module,2106 mod: *Module,
2107 strat: AbiAlignmentAdvancedStrat,2107 strat: AbiAlignmentAdvancedStrat,
2108 ) Module.CompileError!AbiAlignmentAdvanced {2108 ) Module.CompileError!AbiAlignmentAdvanced {
2109 const target = mod.getTarget();2109 const target = mod.getTarget();
...@@ -2320,7 +2320,7 @@ pub const Type = struct {...@@ -2320,7 +2320,7 @@ pub const Type = struct {
2320 },2320 },
23212321
2322 .enum_full, .enum_nonexhaustive, .enum_simple, .enum_numbered => {2322 .enum_full, .enum_nonexhaustive, .enum_simple, .enum_numbered => {
2323 const int_tag_ty = ty.intTagType();2323 const int_tag_ty = try ty.intTagType(mod);
2324 return AbiAlignmentAdvanced{ .scalar = int_tag_ty.abiAlignment(mod) };2324 return AbiAlignmentAdvanced{ .scalar = int_tag_ty.abiAlignment(mod) };
2325 },2325 },
2326 .@"union" => {2326 .@"union" => {
...@@ -2344,7 +2344,7 @@ pub const Type = struct {...@@ -2344,7 +2344,7 @@ pub const Type = struct {
23442344
2345 fn abiAlignmentAdvancedErrorUnion(2345 fn abiAlignmentAdvancedErrorUnion(
2346 ty: Type,2346 ty: Type,
2347 mod: *const Module,2347 mod: *Module,
2348 strat: AbiAlignmentAdvancedStrat,2348 strat: AbiAlignmentAdvancedStrat,
2349 ) Module.CompileError!AbiAlignmentAdvanced {2349 ) Module.CompileError!AbiAlignmentAdvanced {
2350 // This code needs to be kept in sync with the equivalent switch prong2350 // This code needs to be kept in sync with the equivalent switch prong
...@@ -2380,7 +2380,7 @@ pub const Type = struct {...@@ -2380,7 +2380,7 @@ pub const Type = struct {
23802380
2381 fn abiAlignmentAdvancedOptional(2381 fn abiAlignmentAdvancedOptional(
2382 ty: Type,2382 ty: Type,
2383 mod: *const Module,2383 mod: *Module,
2384 strat: AbiAlignmentAdvancedStrat,2384 strat: AbiAlignmentAdvancedStrat,
2385 ) Module.CompileError!AbiAlignmentAdvanced {2385 ) Module.CompileError!AbiAlignmentAdvanced {
2386 const target = mod.getTarget();2386 const target = mod.getTarget();
...@@ -2412,7 +2412,7 @@ pub const Type = struct {...@@ -2412,7 +2412,7 @@ pub const Type = struct {
24122412
2413 pub fn abiAlignmentAdvancedUnion(2413 pub fn abiAlignmentAdvancedUnion(
2414 ty: Type,2414 ty: Type,
2415 mod: *const Module,2415 mod: *Module,
2416 strat: AbiAlignmentAdvancedStrat,2416 strat: AbiAlignmentAdvancedStrat,
2417 union_obj: *Module.Union,2417 union_obj: *Module.Union,
2418 have_tag: bool,2418 have_tag: bool,
...@@ -2477,7 +2477,7 @@ pub const Type = struct {...@@ -2477,7 +2477,7 @@ pub const Type = struct {
24772477
2478 /// Asserts the type has the ABI size already resolved.2478 /// Asserts the type has the ABI size already resolved.
2479 /// Types that return false for hasRuntimeBits() return 0.2479 /// Types that return false for hasRuntimeBits() return 0.
2480 pub fn abiSize(ty: Type, mod: *const Module) u64 {2480 pub fn abiSize(ty: Type, mod: *Module) u64 {
2481 return (abiSizeAdvanced(ty, mod, .eager) catch unreachable).scalar;2481 return (abiSizeAdvanced(ty, mod, .eager) catch unreachable).scalar;
2482 }2482 }
24832483
...@@ -2494,7 +2494,7 @@ pub const Type = struct {...@@ -2494,7 +2494,7 @@ pub const Type = struct {
2494 /// necessary, possibly returning a CompileError.2494 /// necessary, possibly returning a CompileError.
2495 pub fn abiSizeAdvanced(2495 pub fn abiSizeAdvanced(
2496 ty: Type,2496 ty: Type,
2497 mod: *const Module,2497 mod: *Module,
2498 strat: AbiAlignmentAdvancedStrat,2498 strat: AbiAlignmentAdvancedStrat,
2499 ) Module.CompileError!AbiSizeAdvanced {2499 ) Module.CompileError!AbiSizeAdvanced {
2500 const target = mod.getTarget();2500 const target = mod.getTarget();
...@@ -2661,7 +2661,7 @@ pub const Type = struct {...@@ -2661,7 +2661,7 @@ pub const Type = struct {
2661 },2661 },
26622662
2663 .enum_simple, .enum_full, .enum_nonexhaustive, .enum_numbered => {2663 .enum_simple, .enum_full, .enum_nonexhaustive, .enum_numbered => {
2664 const int_tag_ty = ty.intTagType();2664 const int_tag_ty = try ty.intTagType(mod);
2665 return AbiSizeAdvanced{ .scalar = int_tag_ty.abiSize(mod) };2665 return AbiSizeAdvanced{ .scalar = int_tag_ty.abiSize(mod) };
2666 },2666 },
2667 .@"union" => {2667 .@"union" => {
...@@ -2754,7 +2754,7 @@ pub const Type = struct {...@@ -2754,7 +2754,7 @@ pub const Type = struct {
27542754
2755 pub fn abiSizeAdvancedUnion(2755 pub fn abiSizeAdvancedUnion(
2756 ty: Type,2756 ty: Type,
2757 mod: *const Module,2757 mod: *Module,
2758 strat: AbiAlignmentAdvancedStrat,2758 strat: AbiAlignmentAdvancedStrat,
2759 union_obj: *Module.Union,2759 union_obj: *Module.Union,
2760 have_tag: bool,2760 have_tag: bool,
...@@ -2773,7 +2773,7 @@ pub const Type = struct {...@@ -2773,7 +2773,7 @@ pub const Type = struct {
27732773
2774 fn abiSizeAdvancedOptional(2774 fn abiSizeAdvancedOptional(
2775 ty: Type,2775 ty: Type,
2776 mod: *const Module,2776 mod: *Module,
2777 strat: AbiAlignmentAdvancedStrat,2777 strat: AbiAlignmentAdvancedStrat,
2778 ) Module.CompileError!AbiSizeAdvanced {2778 ) Module.CompileError!AbiSizeAdvanced {
2779 const child_ty = ty.optionalChild(mod);2779 const child_ty = ty.optionalChild(mod);
...@@ -2821,7 +2821,7 @@ pub const Type = struct {...@@ -2821,7 +2821,7 @@ pub const Type = struct {
2821 );2821 );
2822 }2822 }
28232823
2824 pub fn bitSize(ty: Type, mod: *const Module) u64 {2824 pub fn bitSize(ty: Type, mod: *Module) u64 {
2825 return bitSizeAdvanced(ty, mod, null) catch unreachable;2825 return bitSizeAdvanced(ty, mod, null) catch unreachable;
2826 }2826 }
28272827
...@@ -2830,7 +2830,7 @@ pub const Type = struct {...@@ -2830,7 +2830,7 @@ pub const Type = struct {
2830 /// the type is fully resolved, and there will be no error, guaranteed.2830 /// the type is fully resolved, and there will be no error, guaranteed.
2831 pub fn bitSizeAdvanced(2831 pub fn bitSizeAdvanced(
2832 ty: Type,2832 ty: Type,
2833 mod: *const Module,2833 mod: *Module,
2834 opt_sema: ?*Sema,2834 opt_sema: ?*Sema,
2835 ) Module.CompileError!u64 {2835 ) Module.CompileError!u64 {
2836 const target = mod.getTarget();2836 const target = mod.getTarget();
...@@ -2950,7 +2950,7 @@ pub const Type = struct {...@@ -2950,7 +2950,7 @@ pub const Type = struct {
2950 },2950 },
29512951
2952 .enum_simple, .enum_full, .enum_nonexhaustive, .enum_numbered => {2952 .enum_simple, .enum_full, .enum_nonexhaustive, .enum_numbered => {
2953 const int_tag_ty = ty.intTagType();2953 const int_tag_ty = try ty.intTagType(mod);
2954 return try bitSizeAdvanced(int_tag_ty, mod, opt_sema);2954 return try bitSizeAdvanced(int_tag_ty, mod, opt_sema);
2955 },2955 },
29562956
...@@ -3464,11 +3464,11 @@ pub const Type = struct {...@@ -3464,11 +3464,11 @@ pub const Type = struct {
3464 return union_obj.fields.getIndex(name);3464 return union_obj.fields.getIndex(name);
3465 }3465 }
34663466
3467 pub fn unionHasAllZeroBitFieldTypes(ty: Type, mod: *const Module) bool {3467 pub fn unionHasAllZeroBitFieldTypes(ty: Type, mod: *Module) bool {
3468 return ty.cast(Payload.Union).?.data.hasAllZeroBitFieldTypes(mod);3468 return ty.cast(Payload.Union).?.data.hasAllZeroBitFieldTypes(mod);
3469 }3469 }
34703470
3471 pub fn unionGetLayout(ty: Type, mod: *const Module) Module.Union.Layout {3471 pub fn unionGetLayout(ty: Type, mod: *Module) Module.Union.Layout {
3472 switch (ty.tag()) {3472 switch (ty.tag()) {
3473 .@"union" => {3473 .@"union" => {
3474 const union_obj = ty.castTag(.@"union").?.data;3474 const union_obj = ty.castTag(.@"union").?.data;
...@@ -4428,24 +4428,18 @@ pub const Type = struct {...@@ -4428,24 +4428,18 @@ pub const Type = struct {
4428 }4428 }
44294429
4430 /// Asserts the type is an enum or a union.4430 /// Asserts the type is an enum or a union.
4431 pub fn intTagType(ty: Type) Type {4431 pub fn intTagType(ty: Type, mod: *Module) !Type {
4432 switch (ty.tag()) {4432 switch (ty.tag()) {
4433 .enum_full, .enum_nonexhaustive => return ty.cast(Payload.EnumFull).?.data.tag_ty,4433 .enum_full, .enum_nonexhaustive => return ty.cast(Payload.EnumFull).?.data.tag_ty,
4434 .enum_numbered => return ty.castTag(.enum_numbered).?.data.tag_ty,4434 .enum_numbered => return ty.castTag(.enum_numbered).?.data.tag_ty,
4435 .enum_simple => {4435 .enum_simple => {
4436 @panic("TODO move enum_simple to use the intern pool");4436 const enum_simple = ty.castTag(.enum_simple).?.data;
4437 //const enum_simple = ty.castTag(.enum_simple).?.data;4437 const field_count = enum_simple.fields.count();
4438 //const field_count = enum_simple.fields.count();4438 const bits: u16 = if (field_count == 0) 0 else std.math.log2_int_ceil(usize, field_count);
4439 //const bits: u16 = if (field_count == 0) 0 else std.math.log2_int_ceil(usize, field_count);4439 return mod.intType(.unsigned, bits);
4440 //buffer.* = .{
4441 // .base = .{ .tag = .int_unsigned },
4442 // .data = bits,
4443 //};
4444 //return Type.initPayload(&buffer.base);
4445 },4440 },
4446 .union_tagged => {4441 .union_tagged => {
4447 @panic("TODO move union_tagged to use the intern pool");4442 return ty.castTag(.union_tagged).?.data.tag_ty.intTagType(mod);
4448 //return ty.castTag(.union_tagged).?.data.tag_ty.intTagType(buffer),
4449 },4443 },
4450 else => unreachable,4444 else => unreachable,
4451 }4445 }
...@@ -4628,7 +4622,7 @@ pub const Type = struct {...@@ -4628,7 +4622,7 @@ pub const Type = struct {
4628 }4622 }
4629 }4623 }
46304624
4631 pub fn structFieldAlign(ty: Type, index: usize, mod: *const Module) u32 {4625 pub fn structFieldAlign(ty: Type, index: usize, mod: *Module) u32 {
4632 switch (ty.tag()) {4626 switch (ty.tag()) {
4633 .@"struct" => {4627 .@"struct" => {
4634 const struct_obj = ty.castTag(.@"struct").?.data;4628 const struct_obj = ty.castTag(.@"struct").?.data;
...@@ -4718,7 +4712,7 @@ pub const Type = struct {...@@ -4718,7 +4712,7 @@ pub const Type = struct {
4718 }4712 }
4719 }4713 }
47204714
4721 pub fn packedStructFieldByteOffset(ty: Type, field_index: usize, mod: *const Module) u32 {4715 pub fn packedStructFieldByteOffset(ty: Type, field_index: usize, mod: *Module) u32 {
4722 const struct_obj = ty.castTag(.@"struct").?.data;4716 const struct_obj = ty.castTag(.@"struct").?.data;
4723 assert(struct_obj.layout == .Packed);4717 assert(struct_obj.layout == .Packed);
4724 comptime assert(Type.packed_struct_layout_version == 2);4718 comptime assert(Type.packed_struct_layout_version == 2);
...@@ -4750,7 +4744,7 @@ pub const Type = struct {...@@ -4750,7 +4744,7 @@ pub const Type = struct {
4750 offset: u64 = 0,4744 offset: u64 = 0,
4751 big_align: u32 = 0,4745 big_align: u32 = 0,
4752 struct_obj: *Module.Struct,4746 struct_obj: *Module.Struct,
4753 module: *const Module,4747 module: *Module,
47544748
4755 pub fn next(it: *StructOffsetIterator) ?FieldOffset {4749 pub fn next(it: *StructOffsetIterator) ?FieldOffset {
4756 const mod = it.module;4750 const mod = it.module;
...@@ -4779,7 +4773,7 @@ pub const Type = struct {...@@ -4779,7 +4773,7 @@ pub const Type = struct {
47794773
4780 /// Get an iterator that iterates over all the struct field, returning the field and4774 /// Get an iterator that iterates over all the struct field, returning the field and
4781 /// offset of that field. Asserts that the type is a non-packed struct.4775 /// offset of that field. Asserts that the type is a non-packed struct.
4782 pub fn iterateStructOffsets(ty: Type, mod: *const Module) StructOffsetIterator {4776 pub fn iterateStructOffsets(ty: Type, mod: *Module) StructOffsetIterator {
4783 const struct_obj = ty.castTag(.@"struct").?.data;4777 const struct_obj = ty.castTag(.@"struct").?.data;
4784 assert(struct_obj.haveLayout());4778 assert(struct_obj.haveLayout());
4785 assert(struct_obj.layout != .Packed);4779 assert(struct_obj.layout != .Packed);
...@@ -4787,7 +4781,7 @@ pub const Type = struct {...@@ -4787,7 +4781,7 @@ pub const Type = struct {
4787 }4781 }
47884782
4789 /// Supports structs and unions.4783 /// Supports structs and unions.
4790 pub fn structFieldOffset(ty: Type, index: usize, mod: *const Module) u64 {4784 pub fn structFieldOffset(ty: Type, index: usize, mod: *Module) u64 {
4791 switch (ty.tag()) {4785 switch (ty.tag()) {
4792 .@"struct" => {4786 .@"struct" => {
4793 const struct_obj = ty.castTag(.@"struct").?.data;4787 const struct_obj = ty.castTag(.@"struct").?.data;
...@@ -5226,7 +5220,7 @@ pub const Type = struct {...@@ -5226,7 +5220,7 @@ pub const Type = struct {
52265220
5227 pub const VectorIndex = InternPool.Key.PtrType.VectorIndex;5221 pub const VectorIndex = InternPool.Key.PtrType.VectorIndex;
52285222
5229 pub fn alignment(data: Data, mod: *const Module) u32 {5223 pub fn alignment(data: Data, mod: *Module) u32 {
5230 if (data.@"align" != 0) return data.@"align";5224 if (data.@"align" != 0) return data.@"align";
5231 return abiAlignment(data.pointee_type, mod);5225 return abiAlignment(data.pointee_type, mod);
5232 }5226 }
src/value.zig+23-21
...@@ -694,7 +694,7 @@ pub const Value = struct {...@@ -694,7 +694,7 @@ pub const Value = struct {
694 },694 },
695 .enum_simple => {695 .enum_simple => {
696 // Field index and integer values are the same.696 // Field index and integer values are the same.
697 const tag_ty = ty.intTagType();697 const tag_ty = try ty.intTagType(mod);
698 return mod.intValue(tag_ty, field_index);698 return mod.intValue(tag_ty, field_index);
699 },699 },
700 else => unreachable,700 else => unreachable,
...@@ -722,7 +722,9 @@ pub const Value = struct {...@@ -722,7 +722,9 @@ pub const Value = struct {
722 // auto-numbered enum722 // auto-numbered enum
723 break :field_index @intCast(u32, val.toUnsignedInt(mod));723 break :field_index @intCast(u32, val.toUnsignedInt(mod));
724 }724 }
725 const int_tag_ty = ty.intTagType();725 const int_tag_ty = ty.intTagType(mod) catch |err| switch (err) {
726 error.OutOfMemory => @panic("OOM"), // TODO handle this failure
727 };
726 break :field_index @intCast(u32, values.getIndexContext(val, .{ .ty = int_tag_ty, .mod = mod }).?);728 break :field_index @intCast(u32, values.getIndexContext(val, .{ .ty = int_tag_ty, .mod = mod }).?);
727 },729 },
728 };730 };
...@@ -737,7 +739,7 @@ pub const Value = struct {...@@ -737,7 +739,7 @@ pub const Value = struct {
737 }739 }
738740
739 /// Asserts the value is an integer.741 /// Asserts the value is an integer.
740 pub fn toBigInt(val: Value, space: *BigIntSpace, mod: *const Module) BigIntConst {742 pub fn toBigInt(val: Value, space: *BigIntSpace, mod: *Module) BigIntConst {
741 return val.toBigIntAdvanced(space, mod, null) catch unreachable;743 return val.toBigIntAdvanced(space, mod, null) catch unreachable;
742 }744 }
743745
...@@ -745,7 +747,7 @@ pub const Value = struct {...@@ -745,7 +747,7 @@ pub const Value = struct {
745 pub fn toBigIntAdvanced(747 pub fn toBigIntAdvanced(
746 val: Value,748 val: Value,
747 space: *BigIntSpace,749 space: *BigIntSpace,
748 mod: *const Module,750 mod: *Module,
749 opt_sema: ?*Sema,751 opt_sema: ?*Sema,
750 ) Module.CompileError!BigIntConst {752 ) Module.CompileError!BigIntConst {
751 return switch (val.ip_index) {753 return switch (val.ip_index) {
...@@ -801,13 +803,13 @@ pub const Value = struct {...@@ -801,13 +803,13 @@ pub const Value = struct {
801803
802 /// If the value fits in a u64, return it, otherwise null.804 /// If the value fits in a u64, return it, otherwise null.
803 /// Asserts not undefined.805 /// Asserts not undefined.
804 pub fn getUnsignedInt(val: Value, mod: *const Module) ?u64 {806 pub fn getUnsignedInt(val: Value, mod: *Module) ?u64 {
805 return getUnsignedIntAdvanced(val, mod, null) catch unreachable;807 return getUnsignedIntAdvanced(val, mod, null) catch unreachable;
806 }808 }
807809
808 /// If the value fits in a u64, return it, otherwise null.810 /// If the value fits in a u64, return it, otherwise null.
809 /// Asserts not undefined.811 /// Asserts not undefined.
810 pub fn getUnsignedIntAdvanced(val: Value, mod: *const Module, opt_sema: ?*Sema) !?u64 {812 pub fn getUnsignedIntAdvanced(val: Value, mod: *Module, opt_sema: ?*Sema) !?u64 {
811 switch (val.ip_index) {813 switch (val.ip_index) {
812 .bool_false => return 0,814 .bool_false => return 0,
813 .bool_true => return 1,815 .bool_true => return 1,
...@@ -847,12 +849,12 @@ pub const Value = struct {...@@ -847,12 +849,12 @@ pub const Value = struct {
847 }849 }
848850
849 /// Asserts the value is an integer and it fits in a u64851 /// Asserts the value is an integer and it fits in a u64
850 pub fn toUnsignedInt(val: Value, mod: *const Module) u64 {852 pub fn toUnsignedInt(val: Value, mod: *Module) u64 {
851 return getUnsignedInt(val, mod).?;853 return getUnsignedInt(val, mod).?;
852 }854 }
853855
854 /// Asserts the value is an integer and it fits in a i64856 /// Asserts the value is an integer and it fits in a i64
855 pub fn toSignedInt(val: Value, mod: *const Module) i64 {857 pub fn toSignedInt(val: Value, mod: *Module) i64 {
856 switch (val.ip_index) {858 switch (val.ip_index) {
857 .bool_false => return 0,859 .bool_false => return 0,
858 .bool_true => return 1,860 .bool_true => return 1,
...@@ -1405,7 +1407,7 @@ pub const Value = struct {...@@ -1405,7 +1407,7 @@ pub const Value = struct {
1405 }1407 }
1406 }1408 }
14071409
1408 pub fn clz(val: Value, ty: Type, mod: *const Module) u64 {1410 pub fn clz(val: Value, ty: Type, mod: *Module) u64 {
1409 const ty_bits = ty.intInfo(mod).bits;1411 const ty_bits = ty.intInfo(mod).bits;
1410 return switch (val.ip_index) {1412 return switch (val.ip_index) {
1411 .bool_false => ty_bits,1413 .bool_false => ty_bits,
...@@ -1435,7 +1437,7 @@ pub const Value = struct {...@@ -1435,7 +1437,7 @@ pub const Value = struct {
1435 };1437 };
1436 }1438 }
14371439
1438 pub fn ctz(val: Value, ty: Type, mod: *const Module) u64 {1440 pub fn ctz(val: Value, ty: Type, mod: *Module) u64 {
1439 const ty_bits = ty.intInfo(mod).bits;1441 const ty_bits = ty.intInfo(mod).bits;
1440 return switch (val.ip_index) {1442 return switch (val.ip_index) {
1441 .bool_false => ty_bits,1443 .bool_false => ty_bits,
...@@ -1468,7 +1470,7 @@ pub const Value = struct {...@@ -1468,7 +1470,7 @@ pub const Value = struct {
1468 };1470 };
1469 }1471 }
14701472
1471 pub fn popCount(val: Value, ty: Type, mod: *const Module) u64 {1473 pub fn popCount(val: Value, ty: Type, mod: *Module) u64 {
1472 assert(!val.isUndef());1474 assert(!val.isUndef());
1473 switch (val.ip_index) {1475 switch (val.ip_index) {
1474 .bool_false => return 0,1476 .bool_false => return 0,
...@@ -1527,7 +1529,7 @@ pub const Value = struct {...@@ -1527,7 +1529,7 @@ pub const Value = struct {
15271529
1528 /// Asserts the value is an integer and not undefined.1530 /// Asserts the value is an integer and not undefined.
1529 /// Returns the number of bits the value requires to represent stored in twos complement form.1531 /// Returns the number of bits the value requires to represent stored in twos complement form.
1530 pub fn intBitCountTwosComp(self: Value, mod: *const Module) usize {1532 pub fn intBitCountTwosComp(self: Value, mod: *Module) usize {
1531 const target = mod.getTarget();1533 const target = mod.getTarget();
1532 return switch (self.ip_index) {1534 return switch (self.ip_index) {
1533 .bool_false => 0,1535 .bool_false => 0,
...@@ -1593,13 +1595,13 @@ pub const Value = struct {...@@ -1593,13 +1595,13 @@ pub const Value = struct {
1593 };1595 };
1594 }1596 }
15951597
1596 pub fn orderAgainstZero(lhs: Value, mod: *const Module) std.math.Order {1598 pub fn orderAgainstZero(lhs: Value, mod: *Module) std.math.Order {
1597 return orderAgainstZeroAdvanced(lhs, mod, null) catch unreachable;1599 return orderAgainstZeroAdvanced(lhs, mod, null) catch unreachable;
1598 }1600 }
15991601
1600 pub fn orderAgainstZeroAdvanced(1602 pub fn orderAgainstZeroAdvanced(
1601 lhs: Value,1603 lhs: Value,
1602 mod: *const Module,1604 mod: *Module,
1603 opt_sema: ?*Sema,1605 opt_sema: ?*Sema,
1604 ) Module.CompileError!std.math.Order {1606 ) Module.CompileError!std.math.Order {
1605 switch (lhs.ip_index) {1607 switch (lhs.ip_index) {
...@@ -1683,13 +1685,13 @@ pub const Value = struct {...@@ -1683,13 +1685,13 @@ pub const Value = struct {
1683 }1685 }
16841686
1685 /// Asserts the value is comparable.1687 /// Asserts the value is comparable.
1686 pub fn order(lhs: Value, rhs: Value, mod: *const Module) std.math.Order {1688 pub fn order(lhs: Value, rhs: Value, mod: *Module) std.math.Order {
1687 return orderAdvanced(lhs, rhs, mod, null) catch unreachable;1689 return orderAdvanced(lhs, rhs, mod, null) catch unreachable;
1688 }1690 }
16891691
1690 /// Asserts the value is comparable.1692 /// Asserts the value is comparable.
1691 /// If opt_sema is null then this function asserts things are resolved and cannot fail.1693 /// If opt_sema is null then this function asserts things are resolved and cannot fail.
1692 pub fn orderAdvanced(lhs: Value, rhs: Value, mod: *const Module, opt_sema: ?*Sema) !std.math.Order {1694 pub fn orderAdvanced(lhs: Value, rhs: Value, mod: *Module, opt_sema: ?*Sema) !std.math.Order {
1693 const lhs_against_zero = try lhs.orderAgainstZeroAdvanced(mod, opt_sema);1695 const lhs_against_zero = try lhs.orderAgainstZeroAdvanced(mod, opt_sema);
1694 const rhs_against_zero = try rhs.orderAgainstZeroAdvanced(mod, opt_sema);1696 const rhs_against_zero = try rhs.orderAgainstZeroAdvanced(mod, opt_sema);
1695 switch (lhs_against_zero) {1697 switch (lhs_against_zero) {
...@@ -1734,7 +1736,7 @@ pub const Value = struct {...@@ -1734,7 +1736,7 @@ pub const Value = struct {
17341736
1735 /// Asserts the value is comparable. Does not take a type parameter because it supports1737 /// Asserts the value is comparable. Does not take a type parameter because it supports
1736 /// comparisons between heterogeneous types.1738 /// comparisons between heterogeneous types.
1737 pub fn compareHetero(lhs: Value, op: std.math.CompareOperator, rhs: Value, mod: *const Module) bool {1739 pub fn compareHetero(lhs: Value, op: std.math.CompareOperator, rhs: Value, mod: *Module) bool {
1738 return compareHeteroAdvanced(lhs, op, rhs, mod, null) catch unreachable;1740 return compareHeteroAdvanced(lhs, op, rhs, mod, null) catch unreachable;
1739 }1741 }
17401742
...@@ -1742,7 +1744,7 @@ pub const Value = struct {...@@ -1742,7 +1744,7 @@ pub const Value = struct {
1742 lhs: Value,1744 lhs: Value,
1743 op: std.math.CompareOperator,1745 op: std.math.CompareOperator,
1744 rhs: Value,1746 rhs: Value,
1745 mod: *const Module,1747 mod: *Module,
1746 opt_sema: ?*Sema,1748 opt_sema: ?*Sema,
1747 ) !bool {1749 ) !bool {
1748 if (lhs.pointerDecl()) |lhs_decl| {1750 if (lhs.pointerDecl()) |lhs_decl| {
...@@ -2047,7 +2049,7 @@ pub const Value = struct {...@@ -2047,7 +2049,7 @@ pub const Value = struct {
2047 .Enum => {2049 .Enum => {
2048 const a_val = try a.enumToInt(ty, mod);2050 const a_val = try a.enumToInt(ty, mod);
2049 const b_val = try b.enumToInt(ty, mod);2051 const b_val = try b.enumToInt(ty, mod);
2050 const int_ty = ty.intTagType();2052 const int_ty = try ty.intTagType(mod);
2051 return eqlAdvanced(a_val, int_ty, b_val, int_ty, mod, opt_sema);2053 return eqlAdvanced(a_val, int_ty, b_val, int_ty, mod, opt_sema);
2052 },2054 },
2053 .Array, .Vector => {2055 .Array, .Vector => {
...@@ -2462,7 +2464,7 @@ pub const Value = struct {...@@ -2462,7 +2464,7 @@ pub const Value = struct {
2462 };2464 };
2463 }2465 }
24642466
2465 fn hashInt(int_val: Value, hasher: *std.hash.Wyhash, mod: *const Module) void {2467 fn hashInt(int_val: Value, hasher: *std.hash.Wyhash, mod: *Module) void {
2466 var buffer: BigIntSpace = undefined;2468 var buffer: BigIntSpace = undefined;
2467 const big = int_val.toBigInt(&buffer, mod);2469 const big = int_val.toBigInt(&buffer, mod);
2468 std.hash.autoHash(hasher, big.positive);2470 std.hash.autoHash(hasher, big.positive);
...@@ -2471,7 +2473,7 @@ pub const Value = struct {...@@ -2471,7 +2473,7 @@ pub const Value = struct {
2471 }2473 }
2472 }2474 }
24732475
2474 fn hashPtr(ptr_val: Value, hasher: *std.hash.Wyhash, mod: *const Module) void {2476 fn hashPtr(ptr_val: Value, hasher: *std.hash.Wyhash, mod: *Module) void {
2475 switch (ptr_val.tag()) {2477 switch (ptr_val.tag()) {
2476 .decl_ref,2478 .decl_ref,
2477 .decl_ref_mut,2479 .decl_ref_mut,