diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2022-02-23 23:27:49 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2022-02-23 23:59:25 -0700 |
| commit | 6249a24e81b9b3df3d5ca99b57f22470b9ac486c (patch) | |
| tree | 7f9ad767459ce5c1227365368d9034576b04e018 /src/Module.zig | |
| parent | 65c04759709a64d1ad0529623bab804b97c02cbc (diff) | |
| download | zig-6249a24e81b9b3df3d5ca99b57f22470b9ac486c.tar.gz zig-6249a24e81b9b3df3d5ca99b57f22470b9ac486c.zip | |
stage2: integer-backed packed structs
This implements #10113 for the self-hosted compiler only. It removes the
ability to override alignment of packed struct fields, and removes the
ability to put pointers and arrays inside packed structs.
After this commit, nearly all the behavior tests pass for the stage2 llvm
backend that involve packed structs.
I didn't implement the compile errors or compile error tests yet. I'm
waiting until we have stage2 building itself and then I want to rework
the compile error test harness with inspiration from Vexu's arocc test
harness. At that point it should be a much nicer dev experience to work
on compile errors.
Diffstat (limited to 'src/Module.zig')
| -rw-r--r-- | src/Module.zig | 34 |
1 files changed, 25 insertions, 9 deletions
diff --git a/src/Module.zig b/src/Module.zig index be2a2f81d0..e596ab0aba 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -886,15 +886,6 @@ pub const Struct = struct { offset: u32, is_comptime: bool, - /// Returns the field alignment, assuming the struct is packed. - pub fn packedAlignment(field: Field) u32 { - if (field.abi_align.tag() == .abi_align_default) { - return 0; - } else { - return @intCast(u32, field.abi_align.toUnsignedInt()); - } - } - /// Returns the field alignment, assuming the struct is not packed. pub fn normalAlignment(field: Field, target: Target) u32 { if (field.abi_align.tag() == .abi_align_default) { @@ -985,6 +976,31 @@ pub const Struct = struct { => true, }; } + + pub fn packedFieldBitOffset(s: Struct, target: Target, index: usize) u16 { + assert(s.layout == .Packed); + assert(s.haveFieldTypes()); + var bit_sum: u64 = 0; + for (s.fields.values()) |field, i| { + if (i == index) { + return @intCast(u16, bit_sum); + } + bit_sum += field.ty.bitSize(target); + } + return @intCast(u16, bit_sum); + } + + pub fn packedIntegerBits(s: Struct, target: Target) u16 { + return s.packedFieldBitOffset(target, s.fields.count()); + } + + pub fn packedIntegerType(s: Struct, target: Target, buf: *Type.Payload.Bits) Type { + buf.* = .{ + .base = .{ .tag = .int_unsigned }, + .data = s.packedIntegerBits(target), + }; + return Type.initPayload(&buf.base); + } }; /// Represents the data that an enum declaration provides, when the fields |
