aboutsummaryrefslogtreecommitdiff
path: root/src/Module.zig
diff options
context:
space:
mode:
authorkcbanner <kcbanner@gmail.com>2023-09-20 23:53:06 -0400
committerkcbanner <kcbanner@gmail.com>2023-09-23 13:04:56 -0400
commit2fddd767ba20374e7677003c101e60f470c3804c (patch)
tree91ffbed5086771488201cebd82be6e1554ac14b5 /src/Module.zig
parentce919ccf45951856a762ffdb8ef850301cd8c588 (diff)
downloadzig-2fddd767ba20374e7677003c101e60f470c3804c.tar.gz
zig-2fddd767ba20374e7677003c101e60f470c3804c.zip
sema: add support for unions in readFromMemory and writeToMemory
Diffstat (limited to 'src/Module.zig')
-rw-r--r--src/Module.zig28
1 files changed, 28 insertions, 0 deletions
diff --git a/src/Module.zig b/src/Module.zig
index 17a97e6c6d..09e136cde8 100644
--- a/src/Module.zig
+++ b/src/Module.zig
@@ -6607,6 +6607,7 @@ pub fn unionFieldNormalAlignment(mod: *Module, u: InternPool.UnionType, field_in
pub fn unionTagFieldIndex(mod: *Module, u: InternPool.UnionType, enum_tag: Value) ?u32 {
const ip = &mod.intern_pool;
+ if (enum_tag.toIntern() == .undef) return null;
assert(ip.typeOf(enum_tag.toIntern()) == u.enum_tag_ty);
const enum_type = ip.indexToKey(u.enum_tag_ty).enum_type;
return enum_type.tagValueIndex(ip, enum_tag.toIntern());
@@ -6672,3 +6673,30 @@ pub fn structPackedFieldBitOffset(
}
unreachable; // index out of bounds
}
+
+pub fn unionLargestField(mod: *Module, u: InternPool.UnionType) struct {
+ ty: Type,
+ index: u32,
+ size: u64,
+} {
+ const fields = u.field_types.get(&mod.intern_pool);
+ assert(fields.len != 0);
+ var largest_field_ty: Type = undefined;
+ var largest_field_size: u64 = 0;
+ var largest_field_index: u32 = 0;
+ for (fields, 0..) |union_field, i| {
+ const field_ty = union_field.toType();
+ const size: u32 = @intCast(field_ty.abiSize(mod));
+ if (size > largest_field_size) {
+ largest_field_ty = field_ty;
+ largest_field_size = size;
+ largest_field_index = @intCast(i);
+ }
+ }
+
+ return .{
+ .ty = largest_field_ty,
+ .index = largest_field_index,
+ .size = largest_field_size,
+ };
+}