authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2022-10-24 21:22:28-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2022-10-25 05:11:29-04:00
log54326cc55485fa71ce729cd553cb9af9ea816faa
tree78f0fc80d2323a7c4ecc38dab2e44bb1488a247a
parent361035fe7a74fed71303a92d15465daa647ac83e

cbe: implement field_parent_ptr


2 files changed, 41 insertions(+), 12 deletions(-)

src/codegen/c.zig+41-10
......@@ -583,12 +583,12 @@ pub const DeclGen = struct {
583583 };
584584 const byte_offset_val = Value.initPayload(&byte_offset_pl.base);
585585
586 var ptr_u8_pl = ptr_info;
587 ptr_u8_pl.data.pointee_type = Type.u8;
588 const ptr_u8_ty = Type.initPayload(&ptr_u8_pl.base);
586 var u8_ptr_pl = ptr_info;
587 u8_ptr_pl.data.pointee_type = Type.u8;
588 const u8_ptr_ty = Type.initPayload(&u8_ptr_pl.base);
589589
590590 try writer.writeAll("&((");
591 try dg.renderTypecast(writer, ptr_u8_ty);
591 try dg.renderTypecast(writer, u8_ptr_ty);
592592 try writer.writeByte(')');
593593 try dg.renderParentPtr(writer, field_ptr.container_ptr, container_ptr_ty);
594594 return writer.print(")[{}]", .{try dg.fmtIntLiteral(Type.usize, byte_offset_val)});
......@@ -4050,8 +4050,39 @@ fn airStructFieldPtrIndex(f: *Function, inst: Air.Inst.Index, index: u8) !CValue
40504050}
40514051
40524052fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue {
4053 _ = inst;
4054 return f.fail("TODO: C backend: implement airFieldParentPtr", .{});
4053 if (f.liveness.isUnused(inst)) return CValue.none;
4054
4055 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
4056 const extra = f.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;
4057
4058 const struct_ptr_ty = f.air.typeOfIndex(inst);
4059 const field_ptr_ty = f.air.typeOf(extra.field_ptr);
4060 const field_ptr_val = try f.resolveInst(extra.field_ptr);
4061
4062 const target = f.object.dg.module.getTarget();
4063 const struct_ty = struct_ptr_ty.childType();
4064 const field_offset = struct_ty.structFieldOffset(extra.field_index, target);
4065
4066 var field_offset_pl = Value.Payload.I64{
4067 .base = .{ .tag = .int_i64 },
4068 .data = -@intCast(i64, field_offset),
4069 };
4070 const field_offset_val = Value.initPayload(&field_offset_pl.base);
4071
4072 var u8_ptr_pl = field_ptr_ty.ptrInfo();
4073 u8_ptr_pl.data.pointee_type = Type.u8;
4074 const u8_ptr_ty = Type.initPayload(&u8_ptr_pl.base);
4075
4076 const writer = f.object.writer();
4077 const local = try f.allocLocal(struct_ptr_ty, .Const);
4078 try writer.writeAll(" = (");
4079 try f.renderTypecast(writer, struct_ptr_ty);
4080 try writer.writeAll(")&((");
4081 try f.renderTypecast(writer, u8_ptr_ty);
4082 try writer.writeByte(')');
4083 try f.writeCValue(writer, field_ptr_val, .Other);
4084 try writer.print(")[{}];\n", .{try f.fmtIntLiteral(Type.isize, field_offset_val)});
4085 return local;
40554086}
40564087
40574088fn structFieldPtr(f: *Function, inst: Air.Inst.Index, struct_ptr_ty: Type, struct_ptr: CValue, index: u32) !CValue {
......@@ -4089,12 +4120,12 @@ fn structFieldPtr(f: *Function, inst: Air.Inst.Index, struct_ptr_ty: Type, struc
40894120 };
40904121 const byte_offset_val = Value.initPayload(&byte_offset_pl.base);
40914122
4092 var ptr_u8_pl = field_ptr_info;
4093 ptr_u8_pl.data.pointee_type = Type.u8;
4094 const ptr_u8_ty = Type.initPayload(&ptr_u8_pl.base);
4123 var u8_ptr_pl = field_ptr_info;
4124 u8_ptr_pl.data.pointee_type = Type.u8;
4125 const u8_ptr_ty = Type.initPayload(&u8_ptr_pl.base);
40954126
40964127 try writer.writeAll("&((");
4097 try f.renderTypecast(writer, ptr_u8_ty);
4128 try f.renderTypecast(writer, u8_ptr_ty);
40984129 try writer.writeByte(')');
40994130 try f.writeCValue(writer, struct_ptr, .Other);
41004131 try writer.print(")[{}];\n", .{try f.fmtIntLiteral(Type.usize, byte_offset_val)});
test/behavior/field_parent_ptr.zig-2
......@@ -4,7 +4,6 @@ const builtin = @import("builtin");
44test "@fieldParentPtr non-first field" {
55 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
66 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
7 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
87 try testParentFieldPtr(&foo.c);
98 comptime try testParentFieldPtr(&foo.c);
109}
......@@ -12,7 +11,6 @@ test "@fieldParentPtr non-first field" {
1211test "@fieldParentPtr first field" {
1312 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1413 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
15 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1614 try testParentFieldPtrFirst(&foo.a);
1715 comptime try testParentFieldPtrFirst(&foo.a);
1816}