stage2: implement intTagType logic
This commit changes a lot of `*const Module` to `*Module` to make it work, since accessing the integer tag type of an enum might need to mutate the InternPool by adding a new integer type into it. An alternate strategy would be to pre-heat the InternPool with the integer tag type when creating an enum type, which would make it so that intTagType could accept a const Module instead of a mutable one, asserting that the InternPool already had the integer tag type.
This commit is contained in:
@@ -1300,7 +1300,7 @@ pub const DeclGen = struct {
|
||||
}
|
||||
},
|
||||
else => {
|
||||
const int_tag_ty = ty.intTagType();
|
||||
const int_tag_ty = try ty.intTagType(mod);
|
||||
return dg.renderValue(writer, int_tag_ty, val, location);
|
||||
},
|
||||
}
|
||||
@@ -5198,7 +5198,7 @@ fn fieldLocation(
|
||||
container_ty: Type,
|
||||
field_ptr_ty: Type,
|
||||
field_index: u32,
|
||||
mod: *const Module,
|
||||
mod: *Module,
|
||||
) union(enum) {
|
||||
begin: void,
|
||||
field: CValue,
|
||||
@@ -7722,7 +7722,7 @@ const LowerFnRetTyBuffer = struct {
|
||||
values: [1]Value,
|
||||
payload: Type.Payload.AnonStruct,
|
||||
};
|
||||
fn lowerFnRetTy(ret_ty: Type, buffer: *LowerFnRetTyBuffer, mod: *const Module) Type {
|
||||
fn lowerFnRetTy(ret_ty: Type, buffer: *LowerFnRetTyBuffer, mod: *Module) Type {
|
||||
if (ret_ty.zigTypeTag(mod) == .NoReturn) return Type.noreturn;
|
||||
|
||||
if (lowersToArray(ret_ty, mod)) {
|
||||
@@ -7740,7 +7740,7 @@ fn lowerFnRetTy(ret_ty: Type, buffer: *LowerFnRetTyBuffer, mod: *const Module) T
|
||||
return if (ret_ty.hasRuntimeBitsIgnoreComptime(mod)) ret_ty else Type.void;
|
||||
}
|
||||
|
||||
fn lowersToArray(ty: Type, mod: *const Module) bool {
|
||||
fn lowersToArray(ty: Type, mod: *Module) bool {
|
||||
return switch (ty.zigTypeTag(mod)) {
|
||||
.Array, .Vector => return true,
|
||||
else => return ty.isAbiInt(mod) and toCIntBits(@intCast(u32, ty.bitSize(mod))) == null,
|
||||
|
||||
@@ -292,17 +292,17 @@ pub const CType = extern union {
|
||||
.abi = std.math.log2_int(u32, abi_alignment),
|
||||
};
|
||||
}
|
||||
pub fn abiAlign(ty: Type, mod: *const Module) AlignAs {
|
||||
pub fn abiAlign(ty: Type, mod: *Module) AlignAs {
|
||||
const abi_align = ty.abiAlignment(mod);
|
||||
return init(abi_align, abi_align);
|
||||
}
|
||||
pub fn fieldAlign(struct_ty: Type, field_i: usize, mod: *const Module) AlignAs {
|
||||
pub fn fieldAlign(struct_ty: Type, field_i: usize, mod: *Module) AlignAs {
|
||||
return init(
|
||||
struct_ty.structFieldAlign(field_i, mod),
|
||||
struct_ty.structFieldType(field_i).abiAlignment(mod),
|
||||
);
|
||||
}
|
||||
pub fn unionPayloadAlign(union_ty: Type, mod: *const Module) AlignAs {
|
||||
pub fn unionPayloadAlign(union_ty: Type, mod: *Module) AlignAs {
|
||||
const union_obj = union_ty.cast(Type.Payload.Union).?.data;
|
||||
const union_payload_align = union_obj.abiAlignment(mod, false);
|
||||
return init(union_payload_align, union_payload_align);
|
||||
@@ -1897,7 +1897,7 @@ pub const CType = extern union {
|
||||
}
|
||||
}
|
||||
|
||||
fn createFromType(store: *Store.Promoted, ty: Type, mod: *const Module, kind: Kind) !CType {
|
||||
fn createFromType(store: *Store.Promoted, ty: Type, mod: *Module, kind: Kind) !CType {
|
||||
var convert: Convert = undefined;
|
||||
try convert.initType(ty, kind, .{ .imm = .{ .set = &store.set, .mod = mod } });
|
||||
return createFromConvert(store, ty, mod, kind, &convert);
|
||||
|
||||
@@ -1527,7 +1527,7 @@ pub const Object = struct {
|
||||
};
|
||||
const field_index_val = Value.initPayload(&buf_field_index.base);
|
||||
|
||||
const int_ty = ty.intTagType();
|
||||
const int_ty = try ty.intTagType(mod);
|
||||
const int_info = ty.intInfo(mod);
|
||||
assert(int_info.bits != 0);
|
||||
|
||||
@@ -2805,7 +2805,7 @@ pub const DeclGen = struct {
|
||||
return dg.context.intType(info.bits);
|
||||
},
|
||||
.Enum => {
|
||||
const int_ty = t.intTagType();
|
||||
const int_ty = try t.intTagType(mod);
|
||||
const bit_count = int_ty.intInfo(mod).bits;
|
||||
assert(bit_count != 0);
|
||||
return dg.context.intType(bit_count);
|
||||
@@ -4334,7 +4334,9 @@ pub const DeclGen = struct {
|
||||
const mod = dg.module;
|
||||
const int_ty = switch (ty.zigTypeTag(mod)) {
|
||||
.Int => ty,
|
||||
.Enum => ty.intTagType(),
|
||||
.Enum => ty.intTagType(mod) catch |err| switch (err) {
|
||||
error.OutOfMemory => @panic("OOM"),
|
||||
},
|
||||
.Float => {
|
||||
if (!is_rmw_xchg) return null;
|
||||
return dg.context.intType(@intCast(c_uint, ty.abiSize(mod) * 8));
|
||||
@@ -5286,7 +5288,7 @@ pub const FuncGen = struct {
|
||||
const mod = self.dg.module;
|
||||
const scalar_ty = operand_ty.scalarType(mod);
|
||||
const int_ty = switch (scalar_ty.zigTypeTag(mod)) {
|
||||
.Enum => scalar_ty.intTagType(),
|
||||
.Enum => try scalar_ty.intTagType(mod),
|
||||
.Int, .Bool, .Pointer, .ErrorSet => scalar_ty,
|
||||
.Optional => blk: {
|
||||
const payload_ty = operand_ty.optionalChild(mod);
|
||||
@@ -8867,7 +8869,7 @@ pub const FuncGen = struct {
|
||||
defer self.gpa.free(fqn);
|
||||
const llvm_fn_name = try std.fmt.allocPrintZ(arena, "__zig_is_named_enum_value_{s}", .{fqn});
|
||||
|
||||
const int_tag_ty = enum_ty.intTagType();
|
||||
const int_tag_ty = try enum_ty.intTagType(mod);
|
||||
const param_types = [_]*llvm.Type{try self.dg.lowerType(int_tag_ty)};
|
||||
|
||||
const llvm_ret_ty = try self.dg.lowerType(Type.bool);
|
||||
@@ -8950,7 +8952,7 @@ pub const FuncGen = struct {
|
||||
const usize_llvm_ty = try self.dg.lowerType(Type.usize);
|
||||
const slice_alignment = slice_ty.abiAlignment(mod);
|
||||
|
||||
const int_tag_ty = enum_ty.intTagType();
|
||||
const int_tag_ty = try enum_ty.intTagType(mod);
|
||||
const param_types = [_]*llvm.Type{try self.dg.lowerType(int_tag_ty)};
|
||||
|
||||
const fn_type = llvm.functionType(llvm_ret_ty, ¶m_types, param_types.len, .False);
|
||||
@@ -10487,7 +10489,7 @@ fn toLlvmGlobalAddressSpace(wanted_address_space: std.builtin.AddressSpace, targ
|
||||
fn llvmFieldIndex(
|
||||
ty: Type,
|
||||
field_index: usize,
|
||||
mod: *const Module,
|
||||
mod: *Module,
|
||||
ptr_pl_buf: *Type.Payload.Pointer,
|
||||
) ?c_uint {
|
||||
// Detects where we inserted extra padding fields so that we can skip
|
||||
@@ -10564,7 +10566,7 @@ fn llvmFieldIndex(
|
||||
}
|
||||
}
|
||||
|
||||
fn firstParamSRet(fn_info: Type.Payload.Function.Data, mod: *const Module) bool {
|
||||
fn firstParamSRet(fn_info: Type.Payload.Function.Data, mod: *Module) bool {
|
||||
if (!fn_info.return_type.hasRuntimeBitsIgnoreComptime(mod)) return false;
|
||||
|
||||
const target = mod.getTarget();
|
||||
@@ -10593,7 +10595,7 @@ fn firstParamSRet(fn_info: Type.Payload.Function.Data, mod: *const Module) bool
|
||||
}
|
||||
}
|
||||
|
||||
fn firstParamSRetSystemV(ty: Type, mod: *const Module) bool {
|
||||
fn firstParamSRetSystemV(ty: Type, mod: *Module) bool {
|
||||
const class = x86_64_abi.classifySystemV(ty, mod, .ret);
|
||||
if (class[0] == .memory) return true;
|
||||
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
|
||||
|
||||
fn ccAbiPromoteInt(
|
||||
cc: std.builtin.CallingConvention,
|
||||
mod: *const Module,
|
||||
mod: *Module,
|
||||
ty: Type,
|
||||
) ?std.builtin.Signedness {
|
||||
const target = mod.getTarget();
|
||||
@@ -11080,7 +11082,7 @@ fn ccAbiPromoteInt(
|
||||
|
||||
/// This is the one source of truth for whether a type is passed around as an LLVM pointer,
|
||||
/// or as an LLVM value.
|
||||
fn isByRef(ty: Type, mod: *const Module) bool {
|
||||
fn isByRef(ty: Type, mod: *Module) bool {
|
||||
// For tuples and structs, if there are more than this many non-void
|
||||
// fields, then we make it byref, otherwise byval.
|
||||
const max_fields_byval = 0;
|
||||
@@ -11159,7 +11161,7 @@ fn isByRef(ty: Type, mod: *const Module) bool {
|
||||
}
|
||||
}
|
||||
|
||||
fn isScalar(mod: *const Module, ty: Type) bool {
|
||||
fn isScalar(mod: *Module, ty: Type) bool {
|
||||
return switch (ty.zigTypeTag(mod)) {
|
||||
.Void,
|
||||
.Bool,
|
||||
@@ -11344,11 +11346,11 @@ fn buildAllocaInner(
|
||||
return alloca;
|
||||
}
|
||||
|
||||
fn errUnionPayloadOffset(payload_ty: Type, mod: *const Module) u1 {
|
||||
fn errUnionPayloadOffset(payload_ty: Type, mod: *Module) u1 {
|
||||
return @boolToInt(Type.anyerror.abiAlignment(mod) > payload_ty.abiAlignment(mod));
|
||||
}
|
||||
|
||||
fn errUnionErrorOffset(payload_ty: Type, mod: *const Module) u1 {
|
||||
fn errUnionErrorOffset(payload_ty: Type, mod: *Module) u1 {
|
||||
return @boolToInt(Type.anyerror.abiAlignment(mod) <= payload_ty.abiAlignment(mod));
|
||||
}
|
||||
|
||||
|
||||
@@ -745,7 +745,7 @@ pub const DeclGen = struct {
|
||||
.Enum => {
|
||||
const int_val = try val.enumToInt(ty, mod);
|
||||
|
||||
const int_ty = ty.intTagType();
|
||||
const int_ty = try ty.intTagType(mod);
|
||||
|
||||
try self.lower(int_ty, int_val);
|
||||
},
|
||||
@@ -1195,7 +1195,7 @@ pub const DeclGen = struct {
|
||||
return try self.intType(int_info.signedness, int_info.bits);
|
||||
},
|
||||
.Enum => {
|
||||
const tag_ty = ty.intTagType();
|
||||
const tag_ty = try ty.intTagType(mod);
|
||||
return self.resolveType(tag_ty, repr);
|
||||
},
|
||||
.Float => {
|
||||
@@ -3090,7 +3090,7 @@ pub const DeclGen = struct {
|
||||
break :blk if (backing_bits <= 32) @as(u32, 1) else 2;
|
||||
},
|
||||
.Enum => blk: {
|
||||
const int_ty = cond_ty.intTagType();
|
||||
const int_ty = try cond_ty.intTagType(mod);
|
||||
const int_info = int_ty.intInfo(mod);
|
||||
const backing_bits = self.backingIntBits(int_info.bits) orelse {
|
||||
return self.todo("implement composite int switch", .{});
|
||||
|
||||
Reference in New Issue
Block a user