authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-09-25 17:52:50-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-09-25 17:54:52-07:00
log04366576ea4be4959b596ebff7041d17e18d08d8
tree94dceb8f1e846e09356e5b40b884791a7cc314eb
parent15f55b2805541276f491d255f60f501c8cbd1191

stage2: implement `@sizeOf` for non-packed structs


4 files changed, 38 insertions(+), 20 deletions(-)

src/Sema.zig+1-3
......@@ -6575,6 +6575,7 @@ fn zirSizeOf(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErro
65756575 const src = inst_data.src();
65766576 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
65776577 const operand_ty = try sema.resolveType(block, operand_src, inst_data.operand);
6578 try sema.resolveTypeLayout(block, src, operand_ty);
65786579 const target = sema.mod.getTarget();
65796580 const abi_size = switch (operand_ty.zigTypeTag()) {
65806581 .Fn => unreachable,
......@@ -10846,9 +10847,6 @@ pub fn resolveTypeLayout(
1084610847 ty: Type,
1084710848) CompileError!void {
1084810849 switch (ty.zigTypeTag()) {
10849 .Pointer => {
10850 return sema.resolveTypeLayout(block, src, ty.elemType());
10851 },
1085210850 .Struct => {
1085310851 const resolved_ty = try sema.resolveTypeFields(block, src, ty);
1085410852 const struct_obj = resolved_ty.castTag(.@"struct").?.data;
src/type.zig+15-1
......@@ -1765,7 +1765,21 @@ pub const Type = extern union {
17651765 .@"struct" => {
17661766 const s = self.castTag(.@"struct").?.data;
17671767 assert(s.status == .have_layout);
1768 @panic("TODO abiSize struct");
1768 const is_packed = s.layout == .Packed;
1769 if (is_packed) @panic("TODO packed structs");
1770 var size: u64 = 0;
1771 for (s.fields.values()) |field| {
1772 const field_align = a: {
1773 if (field.abi_align.tag() == .abi_align_default) {
1774 break :a field.ty.abiAlignment(target);
1775 } else {
1776 break :a field.abi_align.toUnsignedInt();
1777 }
1778 };
1779 size = std.mem.alignForwardGeneric(u64, size, field_align);
1780 size += field.ty.abiSize(target);
1781 }
1782 return size;
17691783 },
17701784 .enum_simple, .enum_full, .enum_nonexhaustive => {
17711785 var buffer: Payload.Bits = undefined;
test/behavior/struct.zig+21
......@@ -31,3 +31,24 @@ test "return empty struct instance" {
3131fn returnEmptyStructInstance() StructWithNoFields {
3232 return empty_global_instance;
3333}
34
35const StructFoo = struct {
36 a: i32,
37 b: bool,
38 c: f32,
39};
40test "structs" {
41 var foo: StructFoo = undefined;
42 @memset(@ptrCast([*]u8, &foo), 0, @sizeOf(StructFoo));
43 foo.a += 1;
44 foo.b = foo.a == 1;
45 try testFoo(foo);
46 testMutation(&foo);
47 try expect(foo.c == 100);
48}
49fn testFoo(foo: StructFoo) !void {
50 try expect(foo.b);
51}
52fn testMutation(foo: *StructFoo) void {
53 foo.c = 100;
54}
test/behavior/struct_stage1.zig+1-16
......@@ -30,26 +30,11 @@ const VoidStructFieldsFoo = struct {
3030 c: void,
3131};
3232
33test "structs" {
34 var foo: StructFoo = undefined;
35 @memset(@ptrCast([*]u8, &foo), 0, @sizeOf(StructFoo));
36 foo.a += 1;
37 foo.b = foo.a == 1;
38 try testFoo(foo);
39 testMutation(&foo);
40 try expect(foo.c == 100);
41}
4233const StructFoo = struct {
4334 a: i32,
4435 b: bool,
4536 c: f32,
4637};
47fn testFoo(foo: StructFoo) !void {
48 try expect(foo.b);
49}
50fn testMutation(foo: *StructFoo) void {
51 foo.c = 100;
52}
5338
5439const Node = struct {
5540 val: Val,
......@@ -84,7 +69,7 @@ test "struct byval assign" {
8469 try expect(foo2.a == 1234);
8570}
8671
87fn structInitializer() void {
72test "struct initializer" {
8873 const val = Val{ .x = 42 };
8974 try expect(val.x == 42);
9075}