aboutsummaryrefslogtreecommitdiff
path: root/src/codegen
diff options
context:
space:
mode:
authorjacobly0 <jacobly0@users.noreply.github.com>2022-10-12 05:40:59 -0400
committerGitHub <noreply@github.com>2022-10-12 12:40:59 +0300
commit562ac8be48e4a08358da73e556e331e3618f8b4b (patch)
tree3495e59a81924c3a8ff12b8948fe069f01f104cc /src/codegen
parentb47e54ed3f6e5d93fff8a2327c88c903cc0a194c (diff)
downloadzig-562ac8be48e4a08358da73e556e331e3618f8b4b.tar.gz
zig-562ac8be48e4a08358da73e556e331e3618f8b4b.zip
codegen: add support for lowering .field_ptr on a slice
Closes #13068
Diffstat (limited to 'src/codegen')
-rw-r--r--src/codegen/c.zig34
-rw-r--r--src/codegen/llvm.zig9
2 files changed, 31 insertions, 12 deletions
diff --git a/src/codegen/c.zig b/src/codegen/c.zig
index 4a09c09cc9..b25e05e118 100644
--- a/src/codegen/c.zig
+++ b/src/codegen/c.zig
@@ -485,14 +485,24 @@ pub const DeclGen = struct {
const field_ptr = ptr_val.castTag(.field_ptr).?.data;
const container_ty = field_ptr.container_ty;
const index = field_ptr.field_index;
- const field_name = switch (container_ty.zigTypeTag()) {
- .Struct => container_ty.structFields().keys()[index],
- .Union => container_ty.unionFields().keys()[index],
- else => unreachable,
- };
- const field_ty = switch (container_ty.zigTypeTag()) {
- .Struct => container_ty.structFields().values()[index].ty,
- .Union => container_ty.unionFields().values()[index].ty,
+ const FieldInfo = struct { name: []const u8, ty: Type };
+ const field_info: FieldInfo = switch (container_ty.zigTypeTag()) {
+ .Struct => .{
+ .name = container_ty.structFields().keys()[index],
+ .ty = container_ty.structFields().values()[index].ty,
+ },
+ .Union => .{
+ .name = container_ty.unionFields().keys()[index],
+ .ty = container_ty.unionFields().values()[index].ty,
+ },
+ .Pointer => switch (container_ty.ptrSize()) {
+ .Slice => switch (index) {
+ 0 => FieldInfo{ .name = "ptr", .ty = container_ty.childType() },
+ 1 => FieldInfo{ .name = "len", .ty = Type.usize },
+ else => unreachable,
+ },
+ else => unreachable,
+ },
else => unreachable,
};
var container_ptr_ty_pl: Type.Payload.ElemType = .{
@@ -501,16 +511,16 @@ pub const DeclGen = struct {
};
const container_ptr_ty = Type.initPayload(&container_ptr_ty_pl.base);
- if (field_ty.hasRuntimeBitsIgnoreComptime()) {
+ if (field_info.ty.hasRuntimeBitsIgnoreComptime()) {
try writer.writeAll("&(");
try dg.renderParentPtr(writer, field_ptr.container_ptr, container_ptr_ty);
if (field_ptr.container_ty.tag() == .union_tagged or field_ptr.container_ty.tag() == .union_safety_tagged) {
- try writer.print(")->payload.{ }", .{fmtIdent(field_name)});
+ try writer.print(")->payload.{ }", .{fmtIdent(field_info.name)});
} else {
- try writer.print(")->{ }", .{fmtIdent(field_name)});
+ try writer.print(")->{ }", .{fmtIdent(field_info.name)});
}
} else {
- try dg.renderParentPtr(writer, field_ptr.container_ptr, field_ty);
+ try dg.renderParentPtr(writer, field_ptr.container_ptr, field_info.ty);
}
},
.elem_ptr => {
diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig
index 300a24280a..7038606611 100644
--- a/src/codegen/llvm.zig
+++ b/src/codegen/llvm.zig
@@ -3938,6 +3938,15 @@ pub const DeclGen = struct {
const parent_llvm_ty = try dg.lowerType(parent_ty);
break :blk parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
},
+ .Pointer => {
+ assert(parent_ty.isSlice());
+ const indices: [2]*llvm.Value = .{
+ llvm_u32.constInt(0, .False),
+ llvm_u32.constInt(field_index, .False),
+ };
+ const parent_llvm_ty = try dg.lowerType(parent_ty);
+ break :blk parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
+ },
else => unreachable,
}
},