| 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,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 | 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 | } |
| 1078 | 1078 | ||
| 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); |
| 1082 | 1082 | ||
| ... | @@ -1157,7 +1157,7 @@ pub const Struct = struct { | ... | @@ -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 | 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 | } |
| 1172 | 1172 | ||
| 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, |
| 1177 | 1177 | ||
| ... | @@ -1201,7 +1201,7 @@ pub const Struct = struct { | ... | @@ -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 | 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 | } |
| 1415 | 1415 | ||
| 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 | } |
| 1423 | 1423 | ||
| 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 | } |
| 1439 | 1439 | ||
| 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 | } |
| 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 | return u.getLayout(mod, have_tag).abi_size; | 1454 | return u.getLayout(mod, have_tag).abi_size; |
| 1455 | } | 1455 | } |
| 1456 | 1456 | ||
| ... | @@ -1481,7 +1481,7 @@ pub const Union = struct { | ... | @@ -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 | 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 | }; |
| 6992 | 6993 | ||
| 6993 | pub const AtomicPtrAlignmentDiagnostics = struct { | 6994 | pub 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 affect | 7002 | // TODO this function does not take into account CPU features, which can affect |
| 7002 | // this value. Audit this! | 7003 | // this value. Audit this! |
| 7003 | pub fn atomicPtrAlignment( | 7004 | pub 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( |
| 7080 | 7081 | ||
| 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 |
| 8249 | 8249 | ||
| 8250 | fn zirEnumToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 8250 | fn 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); |
| 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 | 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 |
| 8310 | 8309 | ||
| 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); |
| 16272 | 16271 | ||
| 16273 | const is_exhaustive = Value.makeBool(!ty.isNonexhaustiveEnum()); | 16272 | const is_exhaustive = Value.makeBool(!ty.isNonexhaustiveEnum()); |
| 16274 | 16273 | ||
| ... | @@ -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 | }; |
| 16 | 16 | ||
| 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. |
| 18 | pub fn classifyType(ty: Type, mod: *const Module) Class { | 18 | pub fn classifyType(ty: Type, mod: *Module) Class { |
| 19 | std.debug.assert(ty.hasRuntimeBitsIgnoreComptime(mod)); | 19 | std.debug.assert(ty.hasRuntimeBitsIgnoreComptime(mod)); |
| 20 | 20 | ||
| 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 | } |
| 75 | 75 | ||
| 76 | const sret_float_count = 4; | 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 | 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 | } |
| 117 | 117 | ||
| 118 | pub fn getFloatArrayType(ty: Type, mod: *const Module) ?Type { | 118 | pub 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) { |
| 24 | 24 | ||
| 25 | pub const Context = enum { ret, arg }; | 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 | assert(ty.hasRuntimeBitsIgnoreComptime(mod)); | 28 | assert(ty.hasRuntimeBitsIgnoreComptime(mod)); |
| 29 | 29 | ||
| 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 | } |
| 117 | 117 | ||
| 118 | const byval_float_count = 4; | 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 | 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"); |
| 7 | 7 | ||
| 8 | pub const Class = enum { memory, byval, integer, double_integer }; | 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 | const target = mod.getTarget(); | 11 | const target = mod.getTarget(); |
| 12 | std.debug.assert(ty.hasRuntimeBitsIgnoreComptime(mod)); | 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,7 +1436,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { |
| 1436 | 1436 | ||
| 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 | } |
| 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 | 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 { |
| 1713 | 1713 | ||
| 1714 | /// For a given `Type`, will return true when the type will be passed | 1714 | /// For a given `Type`, will return true when the type will be passed |
| 1715 | /// by reference, rather than by value | 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 | 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-simd | 1787 | /// 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 store | 1788 | /// 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. |
| 1790 | fn determineSimdStoreStrategy(ty: Type, mod: *const Module) SimdStoreStrategy { | 1790 | fn 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 represented | 3236 | /// It's illegal to provide a value with a type that cannot be represented |
| 3237 | /// as an integer value. | 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 | 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 { |
| 3793 | 3793 | ||
| 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 | } |
| 6816 | 6816 | ||
| 6817 | const int_tag_ty = enum_ty.intTagType(); | 6817 | const int_tag_ty = try enum_ty.intTagType(mod); |
| 6818 | 6818 | ||
| 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 passed | 21 | /// 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. |
| 24 | pub fn classifyType(ty: Type, mod: *const Module) [2]Class { | 24 | pub 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 as | 94 | /// 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. |
| 96 | pub fn scalarType(ty: Type, mod: *const Module) Type { | 96 | pub 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 | } |
| 2311 | 2311 | ||
| 2312 | fn regClassForType(ty: Type, mod: *const Module) RegisterManager.RegisterBitSet { | 2312 | fn 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 | }; |
| 14 | 14 | ||
| 15 | pub fn classifyWindows(ty: Type, mod: *const Module) Class { | 15 | pub fn classifyWindows(ty: Type, mod: *Module) Class { |
| 16 | // https://docs.microsoft.com/en-gb/cpp/build/x64-calling-convention?view=vs-2017 | 16 | // 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 arguments | 17 | // "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 8 | 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,7 +68,7 @@ pub const Context = enum { ret, arg, other }; |
| 68 | 68 | ||
| 69 | /// There are a maximum of 8 possible return slots. Returned values are in | 69 | /// 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. |
| 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 | 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 | } |
| 1305 | 1305 | ||
| 1306 | pub fn errUnionPayloadOffset(payload_ty: Type, mod: *const Module) u64 { | 1306 | pub 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 | } |
| 1316 | 1316 | ||
| 1317 | pub fn errUnionErrorOffset(payload_ty: Type, mod: *const Module) u64 { | 1317 | pub 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 | }; |
| 7725 | fn lowerFnRetTy(ret_ty: Type, buffer: *LowerFnRetTyBuffer, mod: *const Module) Type { | 7725 | fn 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; |
| 7727 | 7727 | ||
| 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 | } |
| 7742 | 7742 | ||
| 7743 | fn lowersToArray(ty: Type, mod: *const Module) bool { | 7743 | fn 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 | } |
| 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 | 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); |
| 1529 | 1529 | ||
| 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); |
| 1533 | 1533 | ||
| ... | @@ -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}); |
| 8869 | 8871 | ||
| 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)}; |
| 8872 | 8874 | ||
| 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); |
| 8952 | 8954 | ||
| 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)}; |
| 8955 | 8957 | ||
| 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 |
| 10487 | fn llvmFieldIndex( | 10489 | fn 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 skip | 10495 | // 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 | } |
| 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 | if (!fn_info.return_type.hasRuntimeBitsIgnoreComptime(mod)) return false; | 10570 | if (!fn_info.return_type.hasRuntimeBitsIgnoreComptime(mod)) return false; |
| 10569 | 10571 | ||
| 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 | } |
| 10595 | 10597 | ||
| 10596 | fn firstParamSRetSystemV(ty: Type, mod: *const Module) bool { | 10598 | fn 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 |
| 11041 | 11043 | ||
| 11042 | fn ccAbiPromoteInt( | 11044 | fn 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( |
| 11080 | 11082 | ||
| 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. |
| 11083 | fn isByRef(ty: Type, mod: *const Module) bool { | 11085 | fn isByRef(ty: Type, mod: *Module) bool { |
| 11084 | // For tuples and structs, if there are more than this many non-void | 11086 | // 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 | } |
| 11161 | 11163 | ||
| 11162 | fn isScalar(mod: *const Module, ty: Type) bool { | 11164 | fn 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 | } |
| 11346 | 11348 | ||
| 11347 | fn errUnionPayloadOffset(payload_ty: Type, mod: *const Module) u1 { | 11349 | fn 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 | } |
| 11350 | 11352 | ||
| 11351 | fn errUnionErrorOffset(payload_ty: Type, mod: *const Module) u1 { | 11353 | fn 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 | } |
| 11354 | 11356 |
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); |
| 747 | 747 | ||
| 748 | const int_ty = ty.intTagType(); | 748 | const int_ty = try ty.intTagType(mod); |
| 749 | 749 | ||
| 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 | }, |
| 1791 | 1791 | ||
| ... | @@ -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 layout | 1850 | /// 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 layout | 1852 | /// 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 | } |
| 1954 | 1954 | ||
| 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 | } |
| 1958 | 1958 | ||
| 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 | } |
| 1962 | 1962 | ||
| 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 | } |
| 1981 | 1981 | ||
| 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 | } |
| 2020 | 2020 | ||
| 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 | } |
| 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 | 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 | } |
| 2073 | 2073 | ||
| 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 | } |
| 2078 | 2078 | ||
| ... | @@ -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 | }, |
| 2321 | 2321 | ||
| 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 { |
| 2344 | 2344 | ||
| 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 prong | 2350 | // 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 { |
| 2380 | 2380 | ||
| 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 { |
| 2412 | 2412 | ||
| 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 { |
| 2477 | 2477 | ||
| 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 | } |
| 2483 | 2483 | ||
| ... | @@ -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 | }, |
| 2662 | 2662 | ||
| 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 { |
| 2754 | 2754 | ||
| 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 { |
| 2773 | 2773 | ||
| 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 | } |
| 2823 | 2823 | ||
| 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 | } |
| 2827 | 2827 | ||
| ... | @@ -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 | }, |
| 2951 | 2951 | ||
| 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 | }, |
| 2956 | 2956 | ||
| ... | @@ -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 | } |
| 3466 | 3466 | ||
| 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 | } |
| 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 | 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 | } |
| 4429 | 4429 | ||
| 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 | } |
| 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 | 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 | } |
| 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 | 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, |
| 4754 | 4748 | ||
| 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 { |
| 4779 | 4773 | ||
| 4780 | /// Get an iterator that iterates over all the struct field, returning the field and | 4774 | /// 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 | } |
| 4788 | 4782 | ||
| 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 { |
| 5226 | 5220 | ||
| 5227 | pub const VectorIndex = InternPool.Key.PtrType.VectorIndex; | 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 | 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 enum | 722 | // 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 | } |
| 738 | 740 | ||
| 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 | } |
| 743 | 745 | ||
| ... | @@ -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 { |
| 801 | 803 | ||
| 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 | } |
| 807 | 809 | ||
| 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 | } |
| 848 | 850 | ||
| 849 | /// Asserts the value is an integer and it fits in a u64 | 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 | return getUnsignedInt(val, mod).?; | 853 | return getUnsignedInt(val, mod).?; |
| 852 | } | 854 | } |
| 853 | 855 | ||
| 854 | /// Asserts the value is an integer and it fits in a i64 | 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 | 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 | } |
| 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 | 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 | } |
| 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 | 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 | } |
| 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 | 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 { |
| 1527 | 1529 | ||
| 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 | } |
| 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 | return orderAgainstZeroAdvanced(lhs, mod, null) catch unreachable; | 1599 | return orderAgainstZeroAdvanced(lhs, mod, null) catch unreachable; |
| 1598 | } | 1600 | } |
| 1599 | 1601 | ||
| 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 | } |
| 1684 | 1686 | ||
| 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 | } |
| 1689 | 1691 | ||
| 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 { |
| 1734 | 1736 | ||
| 1735 | /// Asserts the value is comparable. Does not take a type parameter because it supports | 1737 | /// 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 | } |
| 1740 | 1742 | ||
| ... | @@ -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 | } |
| 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 | 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 | } |
| 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 | switch (ptr_val.tag()) { | 2477 | switch (ptr_val.tag()) { |
| 2476 | .decl_ref, | 2478 | .decl_ref, |
| 2477 | .decl_ref_mut, | 2479 | .decl_ref_mut, |