aboutsummaryrefslogtreecommitdiff
path: root/src/codegen/c.zig
diff options
context:
space:
mode:
authorJacob Young <jacobly0@users.noreply.github.com>2022-10-24 21:22:28 -0400
committerJacob Young <jacobly0@users.noreply.github.com>2022-10-25 05:11:29 -0400
commit54326cc55485fa71ce729cd553cb9af9ea816faa (patch)
tree78f0fc80d2323a7c4ecc38dab2e44bb1488a247a /src/codegen/c.zig
parent361035fe7a74fed71303a92d15465daa647ac83e (diff)
downloadzig-54326cc55485fa71ce729cd553cb9af9ea816faa.tar.gz
zig-54326cc55485fa71ce729cd553cb9af9ea816faa.zip
cbe: implement field_parent_ptr
Diffstat (limited to 'src/codegen/c.zig')
-rw-r--r--src/codegen/c.zig51
1 files changed, 41 insertions, 10 deletions
diff --git a/src/codegen/c.zig b/src/codegen/c.zig
index 897af5ef65..46215039c4 100644
--- a/src/codegen/c.zig
+++ b/src/codegen/c.zig
@@ -583,12 +583,12 @@ pub const DeclGen = struct {
};
const byte_offset_val = Value.initPayload(&byte_offset_pl.base);
- var ptr_u8_pl = ptr_info;
- ptr_u8_pl.data.pointee_type = Type.u8;
- const ptr_u8_ty = Type.initPayload(&ptr_u8_pl.base);
+ var u8_ptr_pl = ptr_info;
+ u8_ptr_pl.data.pointee_type = Type.u8;
+ const u8_ptr_ty = Type.initPayload(&u8_ptr_pl.base);
try writer.writeAll("&((");
- try dg.renderTypecast(writer, ptr_u8_ty);
+ try dg.renderTypecast(writer, u8_ptr_ty);
try writer.writeByte(')');
try dg.renderParentPtr(writer, field_ptr.container_ptr, container_ptr_ty);
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
}
fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue {
- _ = inst;
- return f.fail("TODO: C backend: implement airFieldParentPtr", .{});
+ if (f.liveness.isUnused(inst)) return CValue.none;
+
+ const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
+ const extra = f.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;
+
+ const struct_ptr_ty = f.air.typeOfIndex(inst);
+ const field_ptr_ty = f.air.typeOf(extra.field_ptr);
+ const field_ptr_val = try f.resolveInst(extra.field_ptr);
+
+ const target = f.object.dg.module.getTarget();
+ const struct_ty = struct_ptr_ty.childType();
+ const field_offset = struct_ty.structFieldOffset(extra.field_index, target);
+
+ var field_offset_pl = Value.Payload.I64{
+ .base = .{ .tag = .int_i64 },
+ .data = -@intCast(i64, field_offset),
+ };
+ const field_offset_val = Value.initPayload(&field_offset_pl.base);
+
+ var u8_ptr_pl = field_ptr_ty.ptrInfo();
+ u8_ptr_pl.data.pointee_type = Type.u8;
+ const u8_ptr_ty = Type.initPayload(&u8_ptr_pl.base);
+
+ const writer = f.object.writer();
+ const local = try f.allocLocal(struct_ptr_ty, .Const);
+ try writer.writeAll(" = (");
+ try f.renderTypecast(writer, struct_ptr_ty);
+ try writer.writeAll(")&((");
+ try f.renderTypecast(writer, u8_ptr_ty);
+ try writer.writeByte(')');
+ try f.writeCValue(writer, field_ptr_val, .Other);
+ try writer.print(")[{}];\n", .{try f.fmtIntLiteral(Type.isize, field_offset_val)});
+ return local;
}
fn 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
};
const byte_offset_val = Value.initPayload(&byte_offset_pl.base);
- var ptr_u8_pl = field_ptr_info;
- ptr_u8_pl.data.pointee_type = Type.u8;
- const ptr_u8_ty = Type.initPayload(&ptr_u8_pl.base);
+ var u8_ptr_pl = field_ptr_info;
+ u8_ptr_pl.data.pointee_type = Type.u8;
+ const u8_ptr_ty = Type.initPayload(&u8_ptr_pl.base);
try writer.writeAll("&((");
- try f.renderTypecast(writer, ptr_u8_ty);
+ try f.renderTypecast(writer, u8_ptr_ty);
try writer.writeByte(')');
try f.writeCValue(writer, struct_ptr, .Other);
try writer.print(")[{}];\n", .{try f.fmtIntLiteral(Type.usize, byte_offset_val)});