aboutsummaryrefslogtreecommitdiff
path: root/src/Module.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2022-02-23 23:27:49 -0700
committerAndrew Kelley <andrew@ziglang.org>2022-02-23 23:59:25 -0700
commit6249a24e81b9b3df3d5ca99b57f22470b9ac486c (patch)
tree7f9ad767459ce5c1227365368d9034576b04e018 /src/Module.zig
parent65c04759709a64d1ad0529623bab804b97c02cbc (diff)
downloadzig-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.zig34
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