mirror of
https://github.com/ziglang/zig.git
synced 2025-12-12 09:13:11 +00:00
LLVM: Make sure child types get added first
The LLVM bitcode requires all type references in structs to be to earlier defined types. We make sure types are ordered in the builder itself in order to avoid having to iterate the types multiple times and changing the values of type indicies.
This commit is contained in:
parent
8feae5d2d5
commit
1d94e9ef83
@ -3406,20 +3406,17 @@ pub const Object = struct {
|
||||
},
|
||||
.simple_type => unreachable,
|
||||
.struct_type => |struct_type| {
|
||||
const gop = try o.type_map.getOrPut(o.gpa, t.toIntern());
|
||||
if (gop.found_existing) return gop.value_ptr.*;
|
||||
if (o.type_map.get(t.toIntern())) |value| return value;
|
||||
|
||||
if (struct_type.layout == .Packed) {
|
||||
const int_ty = try o.lowerType(Type.fromInterned(struct_type.backingIntType(ip).*));
|
||||
gop.value_ptr.* = int_ty;
|
||||
try o.type_map.put(o.gpa, t.toIntern(), int_ty);
|
||||
return int_ty;
|
||||
}
|
||||
|
||||
const name = try o.builder.string(ip.stringToSlice(
|
||||
try mod.declPtr(struct_type.decl.unwrap().?).getFullyQualifiedName(mod),
|
||||
));
|
||||
const ty = try o.builder.opaqueType(name);
|
||||
gop.value_ptr.* = ty; // must be done before any recursive calls
|
||||
|
||||
var llvm_field_types = std.ArrayListUnmanaged(Builder.Type){};
|
||||
defer llvm_field_types.deinit(o.gpa);
|
||||
@ -3484,6 +3481,9 @@ pub const Object = struct {
|
||||
);
|
||||
}
|
||||
|
||||
const ty = try o.builder.opaqueType(name);
|
||||
try o.type_map.put(o.gpa, t.toIntern(), ty);
|
||||
|
||||
try o.builder.namedTypeSetBody(
|
||||
ty,
|
||||
try o.builder.structType(struct_kind, llvm_field_types.items),
|
||||
@ -3553,29 +3553,26 @@ pub const Object = struct {
|
||||
return o.builder.structType(.normal, llvm_field_types.items);
|
||||
},
|
||||
.union_type => |union_type| {
|
||||
const gop = try o.type_map.getOrPut(o.gpa, t.toIntern());
|
||||
if (gop.found_existing) return gop.value_ptr.*;
|
||||
if (o.type_map.get(t.toIntern())) |value| return value;
|
||||
|
||||
const union_obj = ip.loadUnionType(union_type);
|
||||
const layout = mod.getUnionLayout(union_obj);
|
||||
|
||||
if (union_obj.flagsPtr(ip).layout == .Packed) {
|
||||
const int_ty = try o.builder.intType(@intCast(t.bitSize(mod)));
|
||||
gop.value_ptr.* = int_ty;
|
||||
try o.type_map.put(o.gpa, t.toIntern(), int_ty);
|
||||
return int_ty;
|
||||
}
|
||||
|
||||
if (layout.payload_size == 0) {
|
||||
const enum_tag_ty = try o.lowerType(Type.fromInterned(union_obj.enum_tag_ty));
|
||||
gop.value_ptr.* = enum_tag_ty;
|
||||
try o.type_map.put(o.gpa, t.toIntern(), enum_tag_ty);
|
||||
return enum_tag_ty;
|
||||
}
|
||||
|
||||
const name = try o.builder.string(ip.stringToSlice(
|
||||
try mod.declPtr(union_obj.decl).getFullyQualifiedName(mod),
|
||||
));
|
||||
const ty = try o.builder.opaqueType(name);
|
||||
gop.value_ptr.* = ty; // must be done before any recursive calls
|
||||
|
||||
const aligned_field_ty = Type.fromInterned(union_obj.field_types.get(ip)[layout.most_aligned_field]);
|
||||
const aligned_field_llvm_ty = try o.lowerType(aligned_field_ty);
|
||||
@ -3595,6 +3592,9 @@ pub const Object = struct {
|
||||
};
|
||||
|
||||
if (layout.tag_size == 0) {
|
||||
const ty = try o.builder.opaqueType(name);
|
||||
try o.type_map.put(o.gpa, t.toIntern(), ty);
|
||||
|
||||
try o.builder.namedTypeSetBody(
|
||||
ty,
|
||||
try o.builder.structType(.normal, &.{payload_ty}),
|
||||
@ -3620,6 +3620,9 @@ pub const Object = struct {
|
||||
llvm_fields_len += 1;
|
||||
}
|
||||
|
||||
const ty = try o.builder.opaqueType(name);
|
||||
try o.type_map.put(o.gpa, t.toIntern(), ty);
|
||||
|
||||
try o.builder.namedTypeSetBody(
|
||||
ty,
|
||||
try o.builder.structType(.normal, llvm_fields[0..llvm_fields_len]),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user