Sema: port reify struct access to use InternPool
This commit is contained in:
committed by
Andrew Kelley
parent
f8b6eb63d5
commit
c473594114
202
src/Sema.zig
202
src/Sema.zig
@@ -18805,6 +18805,7 @@ fn zirReify(
|
||||
const target = mod.getTarget();
|
||||
const tag_index = type_info_ty.unionTagFieldIndex(union_val.tag, mod).?;
|
||||
if (try union_val.val.anyUndef(mod)) return sema.failWithUseOfUndef(block, src);
|
||||
const ip = &mod.intern_pool;
|
||||
switch (@intToEnum(std.builtin.TypeId, tag_index)) {
|
||||
.Type => return Air.Inst.Ref.type_type,
|
||||
.Void => return Air.Inst.Ref.void_type,
|
||||
@@ -18817,10 +18818,12 @@ fn zirReify(
|
||||
.AnyFrame => return sema.failWithUseOfAsync(block, src),
|
||||
.EnumLiteral => return Air.Inst.Ref.enum_literal_type,
|
||||
.Int => {
|
||||
const struct_val = union_val.val.castTag(.aggregate).?.data;
|
||||
// TODO use reflection instead of magic numbers here
|
||||
const signedness_val = struct_val[0];
|
||||
const bits_val = struct_val[1];
|
||||
const fields = ip.typeOf(union_val.val.ip_index).toType().structFields(mod);
|
||||
const signedness_index = fields.getIndex("signedness").?;
|
||||
const bits_index = fields.getIndex("bits").?;
|
||||
|
||||
const signedness_val = try union_val.val.fieldValue(fields.values()[signedness_index].ty, mod, signedness_index);
|
||||
const bits_val = try union_val.val.fieldValue(fields.values()[bits_index].ty, mod, bits_index);
|
||||
|
||||
const signedness = mod.toEnum(std.builtin.Signedness, signedness_val);
|
||||
const bits = @intCast(u16, bits_val.toUnsignedInt(mod));
|
||||
@@ -18828,10 +18831,12 @@ fn zirReify(
|
||||
return sema.addType(ty);
|
||||
},
|
||||
.Vector => {
|
||||
const struct_val = union_val.val.castTag(.aggregate).?.data;
|
||||
// TODO use reflection instead of magic numbers here
|
||||
const len_val = struct_val[0];
|
||||
const child_val = struct_val[1];
|
||||
const fields = ip.typeOf(union_val.val.ip_index).toType().structFields(mod);
|
||||
const len_index = fields.getIndex("len").?;
|
||||
const child_index = fields.getIndex("child").?;
|
||||
|
||||
const len_val = try union_val.val.fieldValue(fields.values()[len_index].ty, mod, len_index);
|
||||
const child_val = try union_val.val.fieldValue(fields.values()[child_index].ty, mod, child_index);
|
||||
|
||||
const len = @intCast(u32, len_val.toUnsignedInt(mod));
|
||||
const child_ty = child_val.toType();
|
||||
@@ -18845,10 +18850,10 @@ fn zirReify(
|
||||
return sema.addType(ty);
|
||||
},
|
||||
.Float => {
|
||||
const struct_val = union_val.val.castTag(.aggregate).?.data;
|
||||
// TODO use reflection instead of magic numbers here
|
||||
// bits: comptime_int,
|
||||
const bits_val = struct_val[0];
|
||||
const fields = ip.typeOf(union_val.val.ip_index).toType().structFields(mod);
|
||||
const bits_index = fields.getIndex("bits").?;
|
||||
|
||||
const bits_val = try union_val.val.fieldValue(fields.values()[bits_index].ty, mod, bits_index);
|
||||
|
||||
const bits = @intCast(u16, bits_val.toUnsignedInt(mod));
|
||||
const ty = switch (bits) {
|
||||
@@ -18862,16 +18867,24 @@ fn zirReify(
|
||||
return sema.addType(ty);
|
||||
},
|
||||
.Pointer => {
|
||||
const struct_val = union_val.val.castTag(.aggregate).?.data;
|
||||
// TODO use reflection instead of magic numbers here
|
||||
const size_val = struct_val[0];
|
||||
const is_const_val = struct_val[1];
|
||||
const is_volatile_val = struct_val[2];
|
||||
const alignment_val = struct_val[3];
|
||||
const address_space_val = struct_val[4];
|
||||
const child_val = struct_val[5];
|
||||
const is_allowzero_val = struct_val[6];
|
||||
const sentinel_val = struct_val[7];
|
||||
const fields = ip.typeOf(union_val.val.ip_index).toType().structFields(mod);
|
||||
const size_index = fields.getIndex("size").?;
|
||||
const is_const_index = fields.getIndex("is_const").?;
|
||||
const is_volatile_index = fields.getIndex("is_volatile").?;
|
||||
const alignment_index = fields.getIndex("alignment").?;
|
||||
const address_space_index = fields.getIndex("address_space").?;
|
||||
const child_index = fields.getIndex("child").?;
|
||||
const is_allowzero_index = fields.getIndex("is_allowzero").?;
|
||||
const sentinel_index = fields.getIndex("sentinel").?;
|
||||
|
||||
const size_val = try union_val.val.fieldValue(fields.values()[size_index].ty, mod, size_index);
|
||||
const is_const_val = try union_val.val.fieldValue(fields.values()[is_const_index].ty, mod, is_const_index);
|
||||
const is_volatile_val = try union_val.val.fieldValue(fields.values()[is_volatile_index].ty, mod, is_volatile_index);
|
||||
const alignment_val = try union_val.val.fieldValue(fields.values()[alignment_index].ty, mod, alignment_index);
|
||||
const address_space_val = try union_val.val.fieldValue(fields.values()[address_space_index].ty, mod, address_space_index);
|
||||
const child_val = try union_val.val.fieldValue(fields.values()[child_index].ty, mod, child_index);
|
||||
const is_allowzero_val = try union_val.val.fieldValue(fields.values()[is_allowzero_index].ty, mod, is_allowzero_index);
|
||||
const sentinel_val = try union_val.val.fieldValue(fields.values()[sentinel_index].ty, mod, sentinel_index);
|
||||
|
||||
if (!try sema.intFitsInType(alignment_val, Type.u32, null)) {
|
||||
return sema.fail(block, src, "alignment must fit in 'u32'", .{});
|
||||
@@ -18954,14 +18967,14 @@ fn zirReify(
|
||||
return sema.addType(ty);
|
||||
},
|
||||
.Array => {
|
||||
const struct_val = union_val.val.castTag(.aggregate).?.data;
|
||||
// TODO use reflection instead of magic numbers here
|
||||
// len: comptime_int,
|
||||
const len_val = struct_val[0];
|
||||
// child: type,
|
||||
const child_val = struct_val[1];
|
||||
// sentinel: ?*const anyopaque,
|
||||
const sentinel_val = struct_val[2];
|
||||
const fields = ip.typeOf(union_val.val.ip_index).toType().structFields(mod);
|
||||
const len_index = fields.getIndex("len").?;
|
||||
const child_index = fields.getIndex("child").?;
|
||||
const sentinel_index = fields.getIndex("sentinel").?;
|
||||
|
||||
const len_val = try union_val.val.fieldValue(fields.values()[len_index].ty, mod, len_index);
|
||||
const child_val = try union_val.val.fieldValue(fields.values()[child_index].ty, mod, child_index);
|
||||
const sentinel_val = try union_val.val.fieldValue(fields.values()[sentinel_index].ty, mod, sentinel_index);
|
||||
|
||||
const len = len_val.toUnsignedInt(mod);
|
||||
const child_ty = child_val.toType();
|
||||
@@ -18977,10 +18990,10 @@ fn zirReify(
|
||||
return sema.addType(ty);
|
||||
},
|
||||
.Optional => {
|
||||
const struct_val = union_val.val.castTag(.aggregate).?.data;
|
||||
// TODO use reflection instead of magic numbers here
|
||||
// child: type,
|
||||
const child_val = struct_val[0];
|
||||
const fields = ip.typeOf(union_val.val.ip_index).toType().structFields(mod);
|
||||
const child_index = fields.getIndex("child").?;
|
||||
|
||||
const child_val = try union_val.val.fieldValue(fields.values()[child_index].ty, mod, child_index);
|
||||
|
||||
const child_ty = child_val.toType();
|
||||
|
||||
@@ -18988,12 +19001,12 @@ fn zirReify(
|
||||
return sema.addType(ty);
|
||||
},
|
||||
.ErrorUnion => {
|
||||
const struct_val = union_val.val.castTag(.aggregate).?.data;
|
||||
// TODO use reflection instead of magic numbers here
|
||||
// error_set: type,
|
||||
const error_set_val = struct_val[0];
|
||||
// payload: type,
|
||||
const payload_val = struct_val[1];
|
||||
const fields = ip.typeOf(union_val.val.ip_index).toType().structFields(mod);
|
||||
const error_set_index = fields.getIndex("error_set").?;
|
||||
const payload_index = fields.getIndex("payload").?;
|
||||
|
||||
const error_set_val = try union_val.val.fieldValue(fields.values()[error_set_index].ty, mod, error_set_index);
|
||||
const payload_val = try union_val.val.fieldValue(fields.values()[payload_index].ty, mod, payload_index);
|
||||
|
||||
const error_set_ty = error_set_val.toType();
|
||||
const payload_ty = payload_val.toType();
|
||||
@@ -19031,19 +19044,18 @@ fn zirReify(
|
||||
return sema.addType(ty);
|
||||
},
|
||||
.Struct => {
|
||||
// TODO use reflection instead of magic numbers here
|
||||
const struct_val = union_val.val.castTag(.aggregate).?.data;
|
||||
// layout: containerlayout,
|
||||
const layout_val = struct_val[0];
|
||||
// backing_int: ?type,
|
||||
const backing_int_val = struct_val[1];
|
||||
// fields: []const enumfield,
|
||||
const fields_val = struct_val[2];
|
||||
// decls: []const declaration,
|
||||
const decls_val = struct_val[3];
|
||||
// is_tuple: bool,
|
||||
const is_tuple_val = struct_val[4];
|
||||
assert(struct_val.len == 5);
|
||||
const fields = ip.typeOf(union_val.val.ip_index).toType().structFields(mod);
|
||||
const layout_index = fields.getIndex("layout").?;
|
||||
const backing_integer_index = fields.getIndex("backing_integer").?;
|
||||
const fields_index = fields.getIndex("fields").?;
|
||||
const decls_index = fields.getIndex("decls").?;
|
||||
const is_tuple_index = fields.getIndex("is_tuple").?;
|
||||
|
||||
const layout_val = try union_val.val.fieldValue(fields.values()[layout_index].ty, mod, layout_index);
|
||||
const backing_integer_val = try union_val.val.fieldValue(fields.values()[backing_integer_index].ty, mod, backing_integer_index);
|
||||
const fields_val = try union_val.val.fieldValue(fields.values()[fields_index].ty, mod, fields_index);
|
||||
const decls_val = try union_val.val.fieldValue(fields.values()[decls_index].ty, mod, decls_index);
|
||||
const is_tuple_val = try union_val.val.fieldValue(fields.values()[is_tuple_index].ty, mod, is_tuple_index);
|
||||
|
||||
const layout = mod.toEnum(std.builtin.Type.ContainerLayout, layout_val);
|
||||
|
||||
@@ -19052,23 +19064,23 @@ fn zirReify(
|
||||
return sema.fail(block, src, "reified structs must have no decls", .{});
|
||||
}
|
||||
|
||||
if (layout != .Packed and !backing_int_val.isNull(mod)) {
|
||||
if (layout != .Packed and !backing_integer_val.isNull(mod)) {
|
||||
return sema.fail(block, src, "non-packed struct does not support backing integer type", .{});
|
||||
}
|
||||
|
||||
return try sema.reifyStruct(block, inst, src, layout, backing_int_val, fields_val, name_strategy, is_tuple_val.toBool(mod));
|
||||
return try sema.reifyStruct(block, inst, src, layout, backing_integer_val, fields_val, name_strategy, is_tuple_val.toBool(mod));
|
||||
},
|
||||
.Enum => {
|
||||
const struct_val: []const Value = union_val.val.castTag(.aggregate).?.data;
|
||||
// TODO use reflection instead of magic numbers here
|
||||
// tag_type: type,
|
||||
const tag_type_val = struct_val[0];
|
||||
// fields: []const EnumField,
|
||||
const fields_val = struct_val[1];
|
||||
// decls: []const Declaration,
|
||||
const decls_val = struct_val[2];
|
||||
// is_exhaustive: bool,
|
||||
const is_exhaustive_val = struct_val[3];
|
||||
const fields = ip.typeOf(union_val.val.ip_index).toType().structFields(mod);
|
||||
const tag_type_index = fields.getIndex("tag_type").?;
|
||||
const fields_index = fields.getIndex("fields").?;
|
||||
const decls_index = fields.getIndex("decls").?;
|
||||
const is_exhaustive_index = fields.getIndex("is_exhaustive").?;
|
||||
|
||||
const tag_type_val = try union_val.val.fieldValue(fields.values()[tag_type_index].ty, mod, tag_type_index);
|
||||
const fields_val = try union_val.val.fieldValue(fields.values()[fields_index].ty, mod, fields_index);
|
||||
const decls_val = try union_val.val.fieldValue(fields.values()[decls_index].ty, mod, decls_index);
|
||||
const is_exhaustive_val = try union_val.val.fieldValue(fields.values()[is_exhaustive_index].ty, mod, is_exhaustive_index);
|
||||
|
||||
// Decls
|
||||
if (decls_val.sliceLen(mod) > 0) {
|
||||
@@ -19160,9 +19172,10 @@ fn zirReify(
|
||||
return sema.analyzeDeclVal(block, src, new_decl_index);
|
||||
},
|
||||
.Opaque => {
|
||||
const struct_val = union_val.val.castTag(.aggregate).?.data;
|
||||
// decls: []const Declaration,
|
||||
const decls_val = struct_val[0];
|
||||
const fields = ip.typeOf(union_val.val.ip_index).toType().structFields(mod);
|
||||
const decls_index = fields.getIndex("decls").?;
|
||||
|
||||
const decls_val = try union_val.val.fieldValue(fields.values()[decls_index].ty, mod, decls_index);
|
||||
|
||||
// Decls
|
||||
if (decls_val.sliceLen(mod) > 0) {
|
||||
@@ -19205,16 +19218,16 @@ fn zirReify(
|
||||
return sema.analyzeDeclVal(block, src, new_decl_index);
|
||||
},
|
||||
.Union => {
|
||||
// TODO use reflection instead of magic numbers here
|
||||
const struct_val = union_val.val.castTag(.aggregate).?.data;
|
||||
// layout: containerlayout,
|
||||
const layout_val = struct_val[0];
|
||||
// tag_type: ?type,
|
||||
const tag_type_val = struct_val[1];
|
||||
// fields: []const enumfield,
|
||||
const fields_val = struct_val[2];
|
||||
// decls: []const declaration,
|
||||
const decls_val = struct_val[3];
|
||||
const fields = ip.typeOf(union_val.val.ip_index).toType().structFields(mod);
|
||||
const layout_index = fields.getIndex("layout").?;
|
||||
const tag_type_index = fields.getIndex("tag_type").?;
|
||||
const fields_index = fields.getIndex("fields").?;
|
||||
const decls_index = fields.getIndex("decls").?;
|
||||
|
||||
const layout_val = try union_val.val.fieldValue(fields.values()[layout_index].ty, mod, layout_index);
|
||||
const tag_type_val = try union_val.val.fieldValue(fields.values()[tag_type_index].ty, mod, tag_type_index);
|
||||
const fields_val = try union_val.val.fieldValue(fields.values()[fields_index].ty, mod, fields_index);
|
||||
const decls_val = try union_val.val.fieldValue(fields.values()[decls_index].ty, mod, decls_index);
|
||||
|
||||
// Decls
|
||||
if (decls_val.sliceLen(mod) > 0) {
|
||||
@@ -19411,25 +19424,28 @@ fn zirReify(
|
||||
return sema.analyzeDeclVal(block, src, new_decl_index);
|
||||
},
|
||||
.Fn => {
|
||||
const struct_val: []const Value = union_val.val.castTag(.aggregate).?.data;
|
||||
// TODO use reflection instead of magic numbers here
|
||||
// calling_convention: CallingConvention,
|
||||
const cc = mod.toEnum(std.builtin.CallingConvention, struct_val[0]);
|
||||
// alignment: comptime_int,
|
||||
const alignment_val = struct_val[1];
|
||||
// is_generic: bool,
|
||||
const is_generic = struct_val[2].toBool(mod);
|
||||
// is_var_args: bool,
|
||||
const is_var_args = struct_val[3].toBool(mod);
|
||||
// return_type: ?type,
|
||||
const return_type_val = struct_val[4];
|
||||
// args: []const Param,
|
||||
const args_val = struct_val[5];
|
||||
const fields = ip.typeOf(union_val.val.ip_index).toType().structFields(mod);
|
||||
const calling_convention_index = fields.getIndex("calling_convention").?;
|
||||
const alignment_index = fields.getIndex("alignment").?;
|
||||
const is_generic_index = fields.getIndex("is_generic").?;
|
||||
const is_var_args_index = fields.getIndex("is_var_args").?;
|
||||
const return_type_index = fields.getIndex("return_type").?;
|
||||
const params_index = fields.getIndex("params").?;
|
||||
|
||||
const calling_convention_val = try union_val.val.fieldValue(fields.values()[calling_convention_index].ty, mod, calling_convention_index);
|
||||
const alignment_val = try union_val.val.fieldValue(fields.values()[alignment_index].ty, mod, alignment_index);
|
||||
const is_generic_val = try union_val.val.fieldValue(fields.values()[is_generic_index].ty, mod, is_generic_index);
|
||||
const is_var_args_val = try union_val.val.fieldValue(fields.values()[is_var_args_index].ty, mod, is_var_args_index);
|
||||
const return_type_val = try union_val.val.fieldValue(fields.values()[return_type_index].ty, mod, return_type_index);
|
||||
const params_val = try union_val.val.fieldValue(fields.values()[params_index].ty, mod, params_index);
|
||||
|
||||
const is_generic = is_generic_val.toBool(mod);
|
||||
if (is_generic) {
|
||||
return sema.fail(block, src, "Type.Fn.is_generic must be false for @Type", .{});
|
||||
}
|
||||
|
||||
const is_var_args = is_var_args_val.toBool(mod);
|
||||
const cc = mod.toEnum(std.builtin.CallingConvention, calling_convention_val);
|
||||
if (is_var_args and cc != .C) {
|
||||
return sema.fail(block, src, "varargs functions must have C calling convention", .{});
|
||||
}
|
||||
@@ -19448,7 +19464,7 @@ fn zirReify(
|
||||
const return_type = return_type_val.optionalValue(mod) orelse
|
||||
return sema.fail(block, src, "Type.Fn.return_type must be non-null for @Type", .{});
|
||||
|
||||
const args_slice_val = args_val.castTag(.slice).?.data;
|
||||
const args_slice_val = params_val.castTag(.slice).?.data;
|
||||
const args_len = try sema.usizeCast(block, src, args_slice_val.len.toUnsignedInt(mod));
|
||||
|
||||
const param_types = try sema.arena.alloc(InternPool.Index, args_len);
|
||||
|
||||
@@ -3148,8 +3148,13 @@ pub const Type = struct {
|
||||
pub fn enumTagFieldIndex(ty: Type, enum_tag: Value, mod: *Module) ?u32 {
|
||||
const ip = &mod.intern_pool;
|
||||
const enum_type = ip.indexToKey(ty.ip_index).enum_type;
|
||||
assert(ip.typeOf(enum_tag.ip_index) == enum_type.tag_ty);
|
||||
return enum_type.tagValueIndex(ip, enum_tag.ip_index);
|
||||
const int_tag = switch (ip.indexToKey(enum_tag.ip_index)) {
|
||||
.int => enum_tag.ip_index,
|
||||
.enum_tag => |info| info.int,
|
||||
else => unreachable,
|
||||
};
|
||||
assert(ip.typeOf(int_tag) == enum_type.tag_ty);
|
||||
return enum_type.tagValueIndex(ip, int_tag);
|
||||
}
|
||||
|
||||
pub fn structFields(ty: Type, mod: *Module) Module.Struct.Fields {
|
||||
|
||||
Reference in New Issue
Block a user