aboutsummaryrefslogtreecommitdiff
path: root/src/Type.zig
diff options
context:
space:
mode:
authorDavid Rubin <daviru007@icloud.com>2024-08-25 22:43:57 -0700
committerDavid Rubin <daviru007@icloud.com>2024-08-25 22:43:57 -0700
commitf777b298327de95d2a54d814ca562c08fd7c7a87 (patch)
treeb6d4b3fe7925911cf861f22b0a668d78c3a6d223 /src/Type.zig
parentce92ccccc961992c00a10e714ce9e799956c50f2 (diff)
downloadzig-f777b298327de95d2a54d814ca562c08fd7c7a87.tar.gz
zig-f777b298327de95d2a54d814ca562c08fd7c7a87.zip
fix up merge conflicts with master
Diffstat (limited to 'src/Type.zig')
-rw-r--r--src/Type.zig63
1 files changed, 61 insertions, 2 deletions
diff --git a/src/Type.zig b/src/Type.zig
index e85e10aacf..5add32a7ac 100644
--- a/src/Type.zig
+++ b/src/Type.zig
@@ -1259,7 +1259,7 @@ pub fn abiSize(ty: Type, zcu: *Zcu) u64 {
}
/// May capture a reference to `ty`.
-pub fn lazyAbiSize(ty: Type, pt: Zcu.PerThread) !Value {
+pub fn abiSizeLazy(ty: Type, pt: Zcu.PerThread) !Value {
switch (try ty.abiSizeInner(.lazy, pt.zcu, pt.tid)) {
.val => |val| return val,
.scalar => |x| return pt.intValue(Type.comptime_int, x),
@@ -3446,7 +3446,7 @@ pub fn structFieldOffset(
const union_type = ip.loadUnionType(ty.toIntern());
if (!union_type.hasTag(ip))
return 0;
- const layout = union_type.getUnionLayout(zcu);
+ const layout = Type.getUnionLayout(union_type, zcu);
if (layout.tag_align.compare(.gte, layout.payload_align)) {
// {Tag, Payload}
return layout.payload_align.forward(layout.tag_size);
@@ -4000,6 +4000,65 @@ fn resolveUnionInner(
};
}
+pub fn getUnionLayout(loaded_union: InternPool.LoadedUnionType, zcu: *Zcu) Zcu.UnionLayout {
+ const ip = &zcu.intern_pool;
+ assert(loaded_union.haveLayout(ip));
+ var most_aligned_field: u32 = undefined;
+ var most_aligned_field_size: u64 = undefined;
+ var biggest_field: u32 = undefined;
+ var payload_size: u64 = 0;
+ var payload_align: InternPool.Alignment = .@"1";
+ for (loaded_union.field_types.get(ip), 0..) |field_ty, field_index| {
+ if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(zcu)) continue;
+
+ const explicit_align = loaded_union.fieldAlign(ip, field_index);
+ const field_align = if (explicit_align != .none)
+ explicit_align
+ else
+ Type.fromInterned(field_ty).abiAlignment(zcu);
+ const field_size = Type.fromInterned(field_ty).abiSize(zcu);
+ if (field_size > payload_size) {
+ payload_size = field_size;
+ biggest_field = @intCast(field_index);
+ }
+ if (field_align.compare(.gte, payload_align)) {
+ payload_align = field_align;
+ most_aligned_field = @intCast(field_index);
+ most_aligned_field_size = field_size;
+ }
+ }
+ const have_tag = loaded_union.flagsUnordered(ip).runtime_tag.hasTag();
+ if (!have_tag or !Type.fromInterned(loaded_union.enum_tag_ty).hasRuntimeBits(zcu)) {
+ return .{
+ .abi_size = payload_align.forward(payload_size),
+ .abi_align = payload_align,
+ .most_aligned_field = most_aligned_field,
+ .most_aligned_field_size = most_aligned_field_size,
+ .biggest_field = biggest_field,
+ .payload_size = payload_size,
+ .payload_align = payload_align,
+ .tag_align = .none,
+ .tag_size = 0,
+ .padding = 0,
+ };
+ }
+
+ const tag_size = Type.fromInterned(loaded_union.enum_tag_ty).abiSize(zcu);
+ const tag_align = Type.fromInterned(loaded_union.enum_tag_ty).abiAlignment(zcu).max(.@"1");
+ return .{
+ .abi_size = loaded_union.sizeUnordered(ip),
+ .abi_align = tag_align.max(payload_align),
+ .most_aligned_field = most_aligned_field,
+ .most_aligned_field_size = most_aligned_field_size,
+ .biggest_field = biggest_field,
+ .payload_size = payload_size,
+ .payload_align = payload_align,
+ .tag_align = tag_align,
+ .tag_size = tag_size,
+ .padding = loaded_union.paddingUnordered(ip),
+ };
+}
+
/// Returns the type of a pointer to an element.
/// Asserts that the type is a pointer, and that the element type is indexable.
/// If the element index is comptime-known, it must be passed in `offset`.