mirror of
https://github.com/ziglang/zig.git
synced 2025-12-25 23:53:15 +00:00
LLVM backend: handle unnamed structs when lowering array values
LLVM doesn't support lowering union values, so we have to use unnamed structs to do it, which means any type that contains a union as an element, even if it is nested in another type, has to have a mechanism to detect when it can't be lowered normally and has to resort itself to an unnamed struct. This includes arrays.
This commit is contained in:
parent
38236533f1
commit
91508e10ab
@ -1371,14 +1371,24 @@ pub const DeclGen = struct {
|
||||
const gpa = dg.gpa;
|
||||
const llvm_elems = try gpa.alloc(*const llvm.Value, elem_vals.len);
|
||||
defer gpa.free(llvm_elems);
|
||||
var need_unnamed = false;
|
||||
for (elem_vals) |elem_val, i| {
|
||||
llvm_elems[i] = try dg.genTypedValue(.{ .ty = elem_ty, .val = elem_val });
|
||||
need_unnamed = need_unnamed or dg.isUnnamedType(elem_ty, llvm_elems[i]);
|
||||
}
|
||||
if (need_unnamed) {
|
||||
return dg.context.constStruct(
|
||||
llvm_elems.ptr,
|
||||
@intCast(c_uint, llvm_elems.len),
|
||||
.True,
|
||||
);
|
||||
} else {
|
||||
const llvm_elem_ty = try dg.llvmType(elem_ty);
|
||||
return llvm_elem_ty.constArray(
|
||||
llvm_elems.ptr,
|
||||
@intCast(c_uint, llvm_elems.len),
|
||||
);
|
||||
}
|
||||
const llvm_elem_ty = try dg.llvmType(elem_ty);
|
||||
return llvm_elem_ty.constArray(
|
||||
llvm_elems.ptr,
|
||||
@intCast(c_uint, llvm_elems.len),
|
||||
);
|
||||
},
|
||||
.repeated => {
|
||||
const val = tv.val.castTag(.repeated).?.data;
|
||||
@ -1389,25 +1399,46 @@ pub const DeclGen = struct {
|
||||
const gpa = dg.gpa;
|
||||
const llvm_elems = try gpa.alloc(*const llvm.Value, len_including_sent);
|
||||
defer gpa.free(llvm_elems);
|
||||
for (llvm_elems[0..len]) |*elem| {
|
||||
elem.* = try dg.genTypedValue(.{ .ty = elem_ty, .val = val });
|
||||
|
||||
var need_unnamed = false;
|
||||
if (len != 0) {
|
||||
for (llvm_elems[0..len]) |*elem| {
|
||||
elem.* = try dg.genTypedValue(.{ .ty = elem_ty, .val = val });
|
||||
}
|
||||
need_unnamed = need_unnamed or dg.isUnnamedType(elem_ty, llvm_elems[0]);
|
||||
}
|
||||
|
||||
if (sentinel) |sent| {
|
||||
llvm_elems[len] = try dg.genTypedValue(.{ .ty = elem_ty, .val = sent });
|
||||
need_unnamed = need_unnamed or dg.isUnnamedType(elem_ty, llvm_elems[len]);
|
||||
}
|
||||
|
||||
if (need_unnamed) {
|
||||
return dg.context.constStruct(
|
||||
llvm_elems.ptr,
|
||||
@intCast(c_uint, llvm_elems.len),
|
||||
.True,
|
||||
);
|
||||
} else {
|
||||
const llvm_elem_ty = try dg.llvmType(elem_ty);
|
||||
return llvm_elem_ty.constArray(
|
||||
llvm_elems.ptr,
|
||||
@intCast(c_uint, llvm_elems.len),
|
||||
);
|
||||
}
|
||||
const llvm_elem_ty = try dg.llvmType(elem_ty);
|
||||
return llvm_elem_ty.constArray(
|
||||
llvm_elems.ptr,
|
||||
@intCast(c_uint, llvm_elems.len),
|
||||
);
|
||||
},
|
||||
.empty_array_sentinel => {
|
||||
const elem_ty = tv.ty.elemType();
|
||||
const sent_val = tv.ty.sentinel().?;
|
||||
const sentinel = try dg.genTypedValue(.{ .ty = elem_ty, .val = sent_val });
|
||||
const llvm_elems: [1]*const llvm.Value = .{sentinel};
|
||||
const llvm_elem_ty = try dg.llvmType(elem_ty);
|
||||
return llvm_elem_ty.constArray(&llvm_elems, llvm_elems.len);
|
||||
const need_unnamed = dg.isUnnamedType(elem_ty, llvm_elems[0]);
|
||||
if (need_unnamed) {
|
||||
return dg.context.constStruct(&llvm_elems, llvm_elems.len, .True);
|
||||
} else {
|
||||
const llvm_elem_ty = try dg.llvmType(elem_ty);
|
||||
return llvm_elem_ty.constArray(&llvm_elems, llvm_elems.len);
|
||||
}
|
||||
},
|
||||
else => unreachable,
|
||||
},
|
||||
@ -1495,7 +1526,7 @@ pub const DeclGen = struct {
|
||||
var llvm_fields = try std.ArrayListUnmanaged(*const llvm.Value).initCapacity(gpa, llvm_field_count);
|
||||
defer llvm_fields.deinit(gpa);
|
||||
|
||||
var make_unnamed_struct = false;
|
||||
var need_unnamed = false;
|
||||
const struct_obj = tv.ty.castTag(.@"struct").?.data;
|
||||
if (struct_obj.layout == .Packed) {
|
||||
const target = dg.module.getTarget();
|
||||
@ -1596,14 +1627,13 @@ pub const DeclGen = struct {
|
||||
.val = field_val,
|
||||
});
|
||||
|
||||
make_unnamed_struct = make_unnamed_struct or
|
||||
dg.isUnnamedType(field_ty, field_llvm_val);
|
||||
need_unnamed = need_unnamed or dg.isUnnamedType(field_ty, field_llvm_val);
|
||||
|
||||
llvm_fields.appendAssumeCapacity(field_llvm_val);
|
||||
}
|
||||
}
|
||||
|
||||
if (make_unnamed_struct) {
|
||||
if (need_unnamed) {
|
||||
return dg.context.constStruct(
|
||||
llvm_fields.items.ptr,
|
||||
@intCast(c_uint, llvm_fields.items.len),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user