mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 14:23:09 +00:00
stage2: implement @sizeOf for non-packed structs
This commit is contained in:
parent
15f55b2805
commit
04366576ea
@ -6575,6 +6575,7 @@ fn zirSizeOf(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErro
|
|||||||
const src = inst_data.src();
|
const src = inst_data.src();
|
||||||
const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
|
const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
|
||||||
const operand_ty = try sema.resolveType(block, operand_src, inst_data.operand);
|
const operand_ty = try sema.resolveType(block, operand_src, inst_data.operand);
|
||||||
|
try sema.resolveTypeLayout(block, src, operand_ty);
|
||||||
const target = sema.mod.getTarget();
|
const target = sema.mod.getTarget();
|
||||||
const abi_size = switch (operand_ty.zigTypeTag()) {
|
const abi_size = switch (operand_ty.zigTypeTag()) {
|
||||||
.Fn => unreachable,
|
.Fn => unreachable,
|
||||||
@ -10846,9 +10847,6 @@ pub fn resolveTypeLayout(
|
|||||||
ty: Type,
|
ty: Type,
|
||||||
) CompileError!void {
|
) CompileError!void {
|
||||||
switch (ty.zigTypeTag()) {
|
switch (ty.zigTypeTag()) {
|
||||||
.Pointer => {
|
|
||||||
return sema.resolveTypeLayout(block, src, ty.elemType());
|
|
||||||
},
|
|
||||||
.Struct => {
|
.Struct => {
|
||||||
const resolved_ty = try sema.resolveTypeFields(block, src, ty);
|
const resolved_ty = try sema.resolveTypeFields(block, src, ty);
|
||||||
const struct_obj = resolved_ty.castTag(.@"struct").?.data;
|
const struct_obj = resolved_ty.castTag(.@"struct").?.data;
|
||||||
|
|||||||
16
src/type.zig
16
src/type.zig
@ -1765,7 +1765,21 @@ pub const Type = extern union {
|
|||||||
.@"struct" => {
|
.@"struct" => {
|
||||||
const s = self.castTag(.@"struct").?.data;
|
const s = self.castTag(.@"struct").?.data;
|
||||||
assert(s.status == .have_layout);
|
assert(s.status == .have_layout);
|
||||||
@panic("TODO abiSize struct");
|
const is_packed = s.layout == .Packed;
|
||||||
|
if (is_packed) @panic("TODO packed structs");
|
||||||
|
var size: u64 = 0;
|
||||||
|
for (s.fields.values()) |field| {
|
||||||
|
const field_align = a: {
|
||||||
|
if (field.abi_align.tag() == .abi_align_default) {
|
||||||
|
break :a field.ty.abiAlignment(target);
|
||||||
|
} else {
|
||||||
|
break :a field.abi_align.toUnsignedInt();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
size = std.mem.alignForwardGeneric(u64, size, field_align);
|
||||||
|
size += field.ty.abiSize(target);
|
||||||
|
}
|
||||||
|
return size;
|
||||||
},
|
},
|
||||||
.enum_simple, .enum_full, .enum_nonexhaustive => {
|
.enum_simple, .enum_full, .enum_nonexhaustive => {
|
||||||
var buffer: Payload.Bits = undefined;
|
var buffer: Payload.Bits = undefined;
|
||||||
|
|||||||
@ -31,3 +31,24 @@ test "return empty struct instance" {
|
|||||||
fn returnEmptyStructInstance() StructWithNoFields {
|
fn returnEmptyStructInstance() StructWithNoFields {
|
||||||
return empty_global_instance;
|
return empty_global_instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const StructFoo = struct {
|
||||||
|
a: i32,
|
||||||
|
b: bool,
|
||||||
|
c: f32,
|
||||||
|
};
|
||||||
|
test "structs" {
|
||||||
|
var foo: StructFoo = undefined;
|
||||||
|
@memset(@ptrCast([*]u8, &foo), 0, @sizeOf(StructFoo));
|
||||||
|
foo.a += 1;
|
||||||
|
foo.b = foo.a == 1;
|
||||||
|
try testFoo(foo);
|
||||||
|
testMutation(&foo);
|
||||||
|
try expect(foo.c == 100);
|
||||||
|
}
|
||||||
|
fn testFoo(foo: StructFoo) !void {
|
||||||
|
try expect(foo.b);
|
||||||
|
}
|
||||||
|
fn testMutation(foo: *StructFoo) void {
|
||||||
|
foo.c = 100;
|
||||||
|
}
|
||||||
|
|||||||
@ -30,26 +30,11 @@ const VoidStructFieldsFoo = struct {
|
|||||||
c: void,
|
c: void,
|
||||||
};
|
};
|
||||||
|
|
||||||
test "structs" {
|
|
||||||
var foo: StructFoo = undefined;
|
|
||||||
@memset(@ptrCast([*]u8, &foo), 0, @sizeOf(StructFoo));
|
|
||||||
foo.a += 1;
|
|
||||||
foo.b = foo.a == 1;
|
|
||||||
try testFoo(foo);
|
|
||||||
testMutation(&foo);
|
|
||||||
try expect(foo.c == 100);
|
|
||||||
}
|
|
||||||
const StructFoo = struct {
|
const StructFoo = struct {
|
||||||
a: i32,
|
a: i32,
|
||||||
b: bool,
|
b: bool,
|
||||||
c: f32,
|
c: f32,
|
||||||
};
|
};
|
||||||
fn testFoo(foo: StructFoo) !void {
|
|
||||||
try expect(foo.b);
|
|
||||||
}
|
|
||||||
fn testMutation(foo: *StructFoo) void {
|
|
||||||
foo.c = 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Node = struct {
|
const Node = struct {
|
||||||
val: Val,
|
val: Val,
|
||||||
@ -84,7 +69,7 @@ test "struct byval assign" {
|
|||||||
try expect(foo2.a == 1234);
|
try expect(foo2.a == 1234);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn structInitializer() void {
|
test "struct initializer" {
|
||||||
const val = Val{ .x = 42 };
|
const val = Val{ .x = 42 };
|
||||||
try expect(val.x == 42);
|
try expect(val.x == 42);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user