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...@@ -6575,6 +6575,7 @@ fn zirSizeOf(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErro
6575 const src = inst_data.src();6575 const src = inst_data.src();
6576 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };6576 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
6577 const operand_ty = try sema.resolveType(block, operand_src, inst_data.operand);6577 const operand_ty = try sema.resolveType(block, operand_src, inst_data.operand);
6578 try sema.resolveTypeLayout(block, src, operand_ty);
6578 const target = sema.mod.getTarget();6579 const target = sema.mod.getTarget();
6579 const abi_size = switch (operand_ty.zigTypeTag()) {6580 const abi_size = switch (operand_ty.zigTypeTag()) {
6580 .Fn => unreachable,6581 .Fn => unreachable,
...@@ -10846,9 +10847,6 @@ pub fn resolveTypeLayout(...@@ -10846,9 +10847,6 @@ pub fn resolveTypeLayout(
10846 ty: Type,10847 ty: Type,
10847) CompileError!void {10848) CompileError!void {
10848 switch (ty.zigTypeTag()) {10849 switch (ty.zigTypeTag()) {
10849 .Pointer => {
10850 return sema.resolveTypeLayout(block, src, ty.elemType());
10851 },
10852 .Struct => {10850 .Struct => {
10853 const resolved_ty = try sema.resolveTypeFields(block, src, ty);10851 const resolved_ty = try sema.resolveTypeFields(block, src, ty);
10854 const struct_obj = resolved_ty.castTag(.@"struct").?.data;10852 const struct_obj = resolved_ty.castTag(.@"struct").?.data;
src/type.zig+15-1
...@@ -1765,7 +1765,21 @@ pub const Type = extern union {...@@ -1765,7 +1765,21 @@ pub const Type = extern union {
1765 .@"struct" => {1765 .@"struct" => {
1766 const s = self.castTag(.@"struct").?.data;1766 const s = self.castTag(.@"struct").?.data;
1767 assert(s.status == .have_layout);1767 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;
1769 },1783 },
1770 .enum_simple, .enum_full, .enum_nonexhaustive => {1784 .enum_simple, .enum_full, .enum_nonexhaustive => {
1771 var buffer: Payload.Bits = undefined;1785 var buffer: Payload.Bits = undefined;
test/behavior/struct.zig+21
...@@ -31,3 +31,24 @@ test "return empty struct instance" {...@@ -31,3 +31,24 @@ test "return empty struct instance" {
31fn returnEmptyStructInstance() StructWithNoFields {31fn returnEmptyStructInstance() StructWithNoFields {
32 return empty_global_instance;32 return empty_global_instance;
33}33}
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 {...@@ -30,26 +30,11 @@ const VoidStructFieldsFoo = struct {
30 c: void,30 c: void,
31};31};
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}
42const StructFoo = struct {33const StructFoo = struct {
43 a: i32,34 a: i32,
44 b: bool,35 b: bool,
45 c: f32,36 c: f32,
46};37};
47fn testFoo(foo: StructFoo) !void {
48 try expect(foo.b);
49}
50fn testMutation(foo: *StructFoo) void {
51 foo.c = 100;
52}
5338
54const Node = struct {39const Node = struct {
55 val: Val,40 val: Val,
...@@ -84,7 +69,7 @@ test "struct byval assign" {...@@ -84,7 +69,7 @@ test "struct byval assign" {
84 try expect(foo2.a == 1234);69 try expect(foo2.a == 1234);
85}70}
8671
87fn structInitializer() void {72test "struct initializer" {
88 const val = Val{ .x = 42 };73 const val = Val{ .x = 42 };
89 try expect(val.x == 42);74 try expect(val.x == 42);
90}75}