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