cbe: fix bugs revealed by an upcoming commit

Closes #18023
This commit is contained in:
Jacob Young
2024-03-28 20:14:16 -04:00
parent aff71c6132
commit 6f10b11658
5 changed files with 1497 additions and 1386 deletions

View File

@@ -165,11 +165,14 @@ typedef char bool;
#endif
#if zig_has_attribute(section)
#define zig_linksection(name, def, ...) def __attribute__((section(name)))
#define zig_linksection(name) __attribute__((section(name)))
#define zig_linksection_fn zig_linksection
#elif _MSC_VER
#define zig_linksection(name, def, ...) __pragma(section(name, __VA_ARGS__)) __declspec(allocate(name)) def
#define zig_linksection(name) __pragma(section(name, read, write)) __declspec(allocate(name))
#define zig_linksection_fn(name) __pragma(section(name, read, execute)) __declspec(code_seg(name))
#else
#define zig_linksection(name, def, ...) zig_linksection_unavailable
#define zig_linksection(name) zig_linksection_unavailable
#define zig_linksection_fn zig_linksection
#endif
#if zig_has_builtin(unreachable) || defined(zig_gnuc)

View File

@@ -3451,7 +3451,8 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: *std.Progress.Node) !v
var dg: c_codegen.DeclGen = .{
.gpa = gpa,
.module = module,
.zcu = module,
.mod = module.namespacePtr(decl.src_namespace).file_scope.mod,
.error_msg = null,
.pass = .{ .decl = decl_index },
.is_naked_fn = false,

File diff suppressed because it is too large Load Diff

View File

@@ -3,10 +3,10 @@ const mem = std.mem;
const Allocator = mem.Allocator;
const assert = std.debug.assert;
const autoHash = std.hash.autoHash;
const Target = std.Target;
const Alignment = @import("../../InternPool.zig").Alignment;
const Module = @import("../../Module.zig");
const Zcu = @import("../../Module.zig");
const Module = @import("../../Package/Module.zig");
const InternPool = @import("../../InternPool.zig");
const Type = @import("../../type.zig").Type;
@@ -280,7 +280,7 @@ pub const CType = extern union {
};
};
pub const AlignAs = struct {
pub const AlignAs = packed struct {
@"align": Alignment,
abi: Alignment,
@@ -298,19 +298,19 @@ pub const CType = extern union {
Alignment.fromNonzeroByteUnits(abi_alignment),
);
}
pub fn abiAlign(ty: Type, mod: *Module) AlignAs {
const abi_align = ty.abiAlignment(mod);
pub fn abiAlign(ty: Type, zcu: *Zcu) AlignAs {
const abi_align = ty.abiAlignment(zcu);
return init(abi_align, abi_align);
}
pub fn fieldAlign(struct_ty: Type, field_i: usize, mod: *Module) AlignAs {
pub fn fieldAlign(struct_ty: Type, field_i: usize, zcu: *Zcu) AlignAs {
return init(
struct_ty.structFieldAlign(field_i, mod),
struct_ty.structFieldType(field_i, mod).abiAlignment(mod),
struct_ty.structFieldAlign(field_i, zcu),
struct_ty.structFieldType(field_i, zcu).abiAlignment(zcu),
);
}
pub fn unionPayloadAlign(union_ty: Type, mod: *Module) AlignAs {
const union_obj = mod.typeToUnion(union_ty).?;
const union_payload_align = mod.unionAbiAlignment(union_obj);
pub fn unionPayloadAlign(union_ty: Type, zcu: *Zcu) AlignAs {
const union_obj = zcu.typeToUnion(union_ty).?;
const union_payload_align = zcu.unionAbiAlignment(union_obj);
return init(union_payload_align, union_payload_align);
}
@@ -356,8 +356,8 @@ pub const CType = extern union {
return self.map.entries.items(.hash)[index - Tag.no_payload_count];
}
pub fn typeToIndex(self: Set, ty: Type, mod: *Module, kind: Kind) ?Index {
const lookup = Convert.Lookup{ .imm = .{ .set = &self, .mod = mod } };
pub fn typeToIndex(self: Set, ty: Type, zcu: *Zcu, mod: *Module, kind: Kind) ?Index {
const lookup = Convert.Lookup{ .imm = .{ .set = &self, .zcu = zcu, .mod = mod } };
var convert: Convert = undefined;
convert.initType(ty, kind, lookup) catch unreachable;
@@ -398,10 +398,11 @@ pub const CType = extern union {
pub fn typeToIndex(
self: *Promoted,
ty: Type,
zcu: *Zcu,
mod: *Module,
kind: Kind,
) Allocator.Error!Index {
const lookup = Convert.Lookup{ .mut = .{ .promoted = self, .mod = mod } };
const lookup = Convert.Lookup{ .mut = .{ .promoted = self, .zcu = zcu, .mod = mod } };
var convert: Convert = undefined;
try convert.initType(ty, kind, lookup);
@@ -417,7 +418,7 @@ pub const CType = extern union {
);
if (!gop.found_existing) {
errdefer _ = self.set.map.pop();
gop.key_ptr.* = try createFromConvert(self, ty, lookup.getModule(), kind, convert);
gop.key_ptr.* = try createFromConvert(self, ty, zcu, mod, kind, convert);
}
if (std.debug.runtime_safety) {
const adapter = TypeAdapter64{
@@ -457,15 +458,15 @@ pub const CType = extern union {
return promoted.cTypeToIndex(cty);
}
pub fn typeToCType(self: *Store, gpa: Allocator, ty: Type, mod: *Module, kind: Kind) !CType {
const idx = try self.typeToIndex(gpa, ty, mod, kind);
pub fn typeToCType(self: *Store, gpa: Allocator, ty: Type, zcu: *Zcu, mod: *Module, kind: Kind) !CType {
const idx = try self.typeToIndex(gpa, ty, zcu, mod, kind);
return self.indexToCType(idx);
}
pub fn typeToIndex(self: *Store, gpa: Allocator, ty: Type, mod: *Module, kind: Kind) !Index {
pub fn typeToIndex(self: *Store, gpa: Allocator, ty: Type, zcu: *Zcu, mod: *Module, kind: Kind) !Index {
var promoted = self.promote(gpa);
defer self.demote(promoted);
return promoted.typeToIndex(ty, mod, kind);
return promoted.typeToIndex(ty, zcu, mod, kind);
}
pub fn clearRetainingCapacity(self: *Store, gpa: Allocator) void {
@@ -549,9 +550,9 @@ pub const CType = extern union {
};
}
pub fn signedness(self: CType, target: std.Target) std.builtin.Signedness {
pub fn signedness(self: CType, mod: *Module) std.builtin.Signedness {
return switch (self.tag()) {
.char => target.charSignedness(),
.char => mod.resolved_target.result.charSignedness(),
.@"signed char",
.short,
.int,
@@ -854,7 +855,8 @@ pub const CType = extern union {
}
}
pub fn floatActiveBits(self: CType, target: Target) u16 {
pub fn floatActiveBits(self: CType, mod: *Module) u16 {
const target = &mod.resolved_target.result;
return switch (self.tag()) {
.float => target.c_type_bit_size(.float),
.double => target.c_type_bit_size(.double),
@@ -868,7 +870,8 @@ pub const CType = extern union {
};
}
pub fn byteSize(self: CType, store: Store.Set, target: Target) u64 {
pub fn byteSize(self: CType, store: Store.Set, mod: *Module) u64 {
const target = &mod.resolved_target.result;
return switch (self.tag()) {
.void => 0,
.char, .@"signed char", ._Bool, .@"unsigned char", .bool, .uint8_t, .int8_t => 1,
@@ -906,7 +909,7 @@ pub const CType = extern union {
.vector,
=> {
const data = self.cast(Payload.Sequence).?.data;
return data.len * store.indexToCType(data.elem_type).byteSize(store, target);
return data.len * store.indexToCType(data.elem_type).byteSize(store, mod);
},
.fwd_anon_struct,
@@ -1248,13 +1251,18 @@ pub const CType = extern union {
}
pub const Lookup = union(enum) {
fail: *Module,
fail: struct {
zcu: *Zcu,
mod: *Module,
},
imm: struct {
set: *const Store.Set,
zcu: *Zcu,
mod: *Module,
},
mut: struct {
promoted: *Store.Promoted,
zcu: *Zcu,
mod: *Module,
},
@@ -1265,15 +1273,15 @@ pub const CType = extern union {
};
}
pub fn getTarget(self: @This()) Target {
return self.getModule().getTarget();
pub fn getZcu(self: @This()) *Zcu {
return switch (self) {
inline else => |pl| pl.zcu,
};
}
pub fn getModule(self: @This()) *Module {
return switch (self) {
.fail => |mod| mod,
.imm => |imm| imm.mod,
.mut => |mut| mut.mod,
inline else => |pl| pl.mod,
};
}
@@ -1288,8 +1296,8 @@ pub const CType = extern union {
pub fn typeToIndex(self: @This(), ty: Type, kind: Kind) !?Index {
return switch (self) {
.fail => null,
.imm => |imm| imm.set.typeToIndex(ty, imm.mod, kind),
.mut => |mut| try mut.promoted.typeToIndex(ty, mut.mod, kind),
.imm => |imm| imm.set.typeToIndex(ty, imm.zcu, imm.mod, kind),
.mut => |mut| try mut.promoted.typeToIndex(ty, mut.zcu, mut.mod, kind),
};
}
@@ -1300,7 +1308,7 @@ pub const CType = extern union {
pub fn freeze(self: @This()) @This() {
return switch (self) {
.fail, .imm => self,
.mut => |mut| .{ .imm = .{ .set = &mut.promoted.set, .mod = mut.mod } },
.mut => |mut| .{ .imm = .{ .set = &mut.promoted.set, .zcu = mut.zcu, .mod = mut.mod } },
};
}
};
@@ -1354,7 +1362,7 @@ pub const CType = extern union {
self.storage.anon.fields[0] = .{
.name = "array",
.type = array_idx,
.alignas = AlignAs.abiAlign(ty, lookup.getModule()),
.alignas = AlignAs.abiAlign(ty, lookup.getZcu()),
};
self.initAnon(kind, fwd_idx, 1);
} else self.init(switch (kind) {
@@ -1366,13 +1374,13 @@ pub const CType = extern union {
}
pub fn initType(self: *@This(), ty: Type, kind: Kind, lookup: Lookup) !void {
const mod = lookup.getModule();
const ip = &mod.intern_pool;
const zcu = lookup.getZcu();
const ip = &zcu.intern_pool;
self.* = undefined;
if (!ty.isFnOrHasRuntimeBitsIgnoreComptime(mod))
if (!ty.isFnOrHasRuntimeBitsIgnoreComptime(zcu))
self.init(.void)
else if (ty.isAbiInt(mod)) switch (ty.ip_index) {
else if (ty.isAbiInt(zcu)) switch (ty.ip_index) {
.usize_type => self.init(.uintptr_t),
.isize_type => self.init(.intptr_t),
.c_char_type => self.init(.char),
@@ -1384,13 +1392,13 @@ pub const CType = extern union {
.c_ulong_type => self.init(.@"unsigned long"),
.c_longlong_type => self.init(.@"long long"),
.c_ulonglong_type => self.init(.@"unsigned long long"),
else => switch (tagFromIntInfo(ty.intInfo(mod))) {
else => switch (tagFromIntInfo(ty.intInfo(zcu))) {
.void => unreachable,
else => |t| self.init(t),
.array => switch (kind) {
.forward, .complete, .global => {
const abi_size = ty.abiSize(mod);
const abi_align = ty.abiAlignment(mod).toByteUnits(0);
const abi_size = ty.abiSize(zcu);
const abi_align = ty.abiAlignment(zcu).toByteUnits(0);
self.storage = .{ .seq = .{ .base = .{ .tag = .array }, .data = .{
.len = @divExact(abi_size, abi_align),
.elem_type = tagFromIntInfo(.{
@@ -1406,7 +1414,7 @@ pub const CType = extern union {
.payload => unreachable,
},
},
} else switch (ty.zigTypeTag(mod)) {
} else switch (ty.zigTypeTag(zcu)) {
.Frame => unreachable,
.AnyFrame => unreachable,
@@ -1436,7 +1444,7 @@ pub const CType = extern union {
}),
.Pointer => {
const info = ty.ptrInfo(mod);
const info = ty.ptrInfo(zcu);
switch (info.flags.size) {
.Slice => {
if (switch (kind) {
@@ -1444,18 +1452,18 @@ pub const CType = extern union {
.complete, .parameter, .global => try lookup.typeToIndex(ty, .forward),
.payload => unreachable,
}) |fwd_idx| {
const ptr_ty = ty.slicePtrFieldType(mod);
const ptr_ty = ty.slicePtrFieldType(zcu);
if (try lookup.typeToIndex(ptr_ty, kind)) |ptr_idx| {
self.storage = .{ .anon = undefined };
self.storage.anon.fields[0] = .{
.name = "ptr",
.type = ptr_idx,
.alignas = AlignAs.abiAlign(ptr_ty, mod),
.alignas = AlignAs.abiAlign(ptr_ty, zcu),
};
self.storage.anon.fields[1] = .{
.name = "len",
.type = Tag.uintptr_t.toIndex(),
.alignas = AlignAs.abiAlign(Type.usize, mod),
.alignas = AlignAs.abiAlign(Type.usize, zcu),
};
self.initAnon(kind, fwd_idx, 2);
} else self.init(switch (kind) {
@@ -1478,11 +1486,16 @@ pub const CType = extern union {
},
};
const pointee_ty = if (info.packed_offset.host_size > 0 and
info.flags.vector_index == .none)
try mod.intType(.unsigned, info.packed_offset.host_size * 8)
const pointee_ty = if (info.packed_offset.host_size > 0 and info.flags.vector_index == .none)
try zcu.intType(.unsigned, info.packed_offset.host_size * 8)
else if (info.flags.alignment == .none or
info.flags.alignment.compareStrict(.gte, Type.fromInterned(info.child).abiAlignment(zcu)))
Type.fromInterned(info.child)
else
Type.fromInterned(info.child);
try zcu.intType(.unsigned, @min(
info.flags.alignment.toByteUnitsOptional().?,
lookup.getModule().resolved_target.result.maxIntAlignment(),
) * 8);
if (try lookup.typeToIndex(pointee_ty, .forward)) |child_idx| {
self.storage = .{ .child = .{
@@ -1495,24 +1508,24 @@ pub const CType = extern union {
}
},
.Struct, .Union => |zig_ty_tag| if (ty.containerLayout(mod) == .@"packed") {
if (mod.typeToPackedStruct(ty)) |packed_struct| {
.Struct, .Union => |zig_ty_tag| if (ty.containerLayout(zcu) == .@"packed") {
if (zcu.typeToPackedStruct(ty)) |packed_struct| {
try self.initType(Type.fromInterned(packed_struct.backingIntType(ip).*), kind, lookup);
} else {
const bits: u16 = @intCast(ty.bitSize(mod));
const int_ty = try mod.intType(.unsigned, bits);
const bits: u16 = @intCast(ty.bitSize(zcu));
const int_ty = try zcu.intType(.unsigned, bits);
try self.initType(int_ty, kind, lookup);
}
} else if (ty.isTupleOrAnonStruct(mod)) {
} else if (ty.isTupleOrAnonStruct(zcu)) {
if (lookup.isMutable()) {
for (0..switch (zig_ty_tag) {
.Struct => ty.structFieldCount(mod),
.Union => mod.typeToUnion(ty).?.field_types.len,
.Struct => ty.structFieldCount(zcu),
.Union => zcu.typeToUnion(ty).?.field_types.len,
else => unreachable,
}) |field_i| {
const field_ty = ty.structFieldType(field_i, mod);
if ((zig_ty_tag == .Struct and ty.structFieldIsComptime(field_i, mod)) or
!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
const field_ty = ty.structFieldType(field_i, zcu);
if ((zig_ty_tag == .Struct and ty.structFieldIsComptime(field_i, zcu)) or
!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
_ = try lookup.typeToIndex(field_ty, switch (kind) {
.forward, .forward_parameter => .forward,
.complete, .parameter => .complete,
@@ -1540,14 +1553,14 @@ pub const CType = extern union {
.payload => unreachable,
});
} else {
const tag_ty = ty.unionTagTypeSafety(mod);
const tag_ty = ty.unionTagTypeSafety(zcu);
const is_tagged_union_wrapper = kind != .payload and tag_ty != null;
const is_struct = zig_ty_tag == .Struct or is_tagged_union_wrapper;
switch (kind) {
.forward, .forward_parameter => {
self.storage = .{ .fwd = .{
.base = .{ .tag = if (is_struct) .fwd_struct else .fwd_union },
.data = ty.getOwnerDecl(mod),
.data = ty.getOwnerDecl(zcu),
} };
self.value = .{ .cty = initPayload(&self.storage.fwd) };
},
@@ -1562,7 +1575,7 @@ pub const CType = extern union {
self.storage.anon.fields[field_count] = .{
.name = "payload",
.type = payload_idx.?,
.alignas = AlignAs.unionPayloadAlign(ty, mod),
.alignas = AlignAs.unionPayloadAlign(ty, zcu),
};
field_count += 1;
}
@@ -1570,7 +1583,7 @@ pub const CType = extern union {
self.storage.anon.fields[field_count] = .{
.name = "tag",
.type = tag_idx.?,
.alignas = AlignAs.abiAlign(tag_ty.?, mod),
.alignas = AlignAs.abiAlign(tag_ty.?, zcu),
};
field_count += 1;
}
@@ -1583,19 +1596,19 @@ pub const CType = extern union {
} };
self.value = .{ .cty = initPayload(&self.storage.anon.pl.complete) };
} else self.init(.@"struct");
} else if (kind == .payload and ty.unionHasAllZeroBitFieldTypes(mod)) {
} else if (kind == .payload and ty.unionHasAllZeroBitFieldTypes(zcu)) {
self.init(.void);
} else {
var is_packed = false;
for (0..switch (zig_ty_tag) {
.Struct => ty.structFieldCount(mod),
.Union => mod.typeToUnion(ty).?.field_types.len,
.Struct => ty.structFieldCount(zcu),
.Union => zcu.typeToUnion(ty).?.field_types.len,
else => unreachable,
}) |field_i| {
const field_ty = ty.structFieldType(field_i, mod);
if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
const field_ty = ty.structFieldType(field_i, zcu);
if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
const field_align = AlignAs.fieldAlign(ty, field_i, mod);
const field_align = AlignAs.fieldAlign(ty, field_i, zcu);
if (field_align.abiOrder().compare(.lt)) {
is_packed = true;
if (!lookup.isMutable()) break;
@@ -1634,9 +1647,9 @@ pub const CType = extern union {
.Vector => .vector,
else => unreachable,
};
if (try lookup.typeToIndex(ty.childType(mod), kind)) |child_idx| {
if (try lookup.typeToIndex(ty.childType(zcu), kind)) |child_idx| {
self.storage = .{ .seq = .{ .base = .{ .tag = t }, .data = .{
.len = ty.arrayLenIncludingSentinel(mod),
.len = ty.arrayLenIncludingSentinel(zcu),
.elem_type = child_idx,
} } };
self.value = .{ .cty = initPayload(&self.storage.seq) };
@@ -1648,9 +1661,9 @@ pub const CType = extern union {
},
.Optional => {
const payload_ty = ty.optionalChild(mod);
if (payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
if (ty.optionalReprIsPayload(mod)) {
const payload_ty = ty.optionalChild(zcu);
if (payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
if (ty.optionalReprIsPayload(zcu)) {
try self.initType(payload_ty, kind, lookup);
} else if (switch (kind) {
.forward, .forward_parameter => @as(Index, undefined),
@@ -1667,12 +1680,12 @@ pub const CType = extern union {
self.storage.anon.fields[0] = .{
.name = "payload",
.type = payload_idx,
.alignas = AlignAs.abiAlign(payload_ty, mod),
.alignas = AlignAs.abiAlign(payload_ty, zcu),
};
self.storage.anon.fields[1] = .{
.name = "is_null",
.type = Tag.bool.toIndex(),
.alignas = AlignAs.abiAlign(Type.bool, mod),
.alignas = AlignAs.abiAlign(Type.bool, zcu),
};
self.initAnon(kind, fwd_idx, 2);
} else self.init(switch (kind) {
@@ -1690,14 +1703,14 @@ pub const CType = extern union {
.complete, .parameter, .global => try lookup.typeToIndex(ty, .forward),
.payload => unreachable,
}) |fwd_idx| {
const payload_ty = ty.errorUnionPayload(mod);
const payload_ty = ty.errorUnionPayload(zcu);
if (try lookup.typeToIndex(payload_ty, switch (kind) {
.forward, .forward_parameter => .forward,
.complete, .parameter => .complete,
.global => .global,
.payload => unreachable,
})) |payload_idx| {
const error_ty = ty.errorUnionSet(mod);
const error_ty = ty.errorUnionSet(zcu);
if (payload_idx == Tag.void.toIndex()) {
try self.initType(error_ty, kind, lookup);
} else if (try lookup.typeToIndex(error_ty, kind)) |error_idx| {
@@ -1705,12 +1718,12 @@ pub const CType = extern union {
self.storage.anon.fields[0] = .{
.name = "payload",
.type = payload_idx,
.alignas = AlignAs.abiAlign(payload_ty, mod),
.alignas = AlignAs.abiAlign(payload_ty, zcu),
};
self.storage.anon.fields[1] = .{
.name = "error",
.type = error_idx,
.alignas = AlignAs.abiAlign(error_ty, mod),
.alignas = AlignAs.abiAlign(error_ty, zcu),
};
self.initAnon(kind, fwd_idx, 2);
} else self.init(switch (kind) {
@@ -1729,7 +1742,7 @@ pub const CType = extern union {
.Opaque => self.init(.void),
.Fn => {
const info = mod.typeToFunc(ty).?;
const info = zcu.typeToFunc(ty).?;
if (!info.is_generic) {
if (lookup.isMutable()) {
const param_kind: Kind = switch (kind) {
@@ -1739,7 +1752,7 @@ pub const CType = extern union {
};
_ = try lookup.typeToIndex(Type.fromInterned(info.return_type), param_kind);
for (info.param_types.get(ip)) |param_type| {
if (!Type.fromInterned(param_type).hasRuntimeBitsIgnoreComptime(mod)) continue;
if (!Type.fromInterned(param_type).hasRuntimeBitsIgnoreComptime(zcu)) continue;
_ = try lookup.typeToIndex(Type.fromInterned(param_type), param_kind);
}
}
@@ -1906,20 +1919,21 @@ pub const CType = extern union {
}
}
fn createFromType(store: *Store.Promoted, ty: Type, mod: *Module, kind: Kind) !CType {
fn createFromType(store: *Store.Promoted, ty: Type, zcu: *Zcu, mod: *Module, kind: Kind) !CType {
var convert: Convert = undefined;
try convert.initType(ty, kind, .{ .imm = .{ .set = &store.set, .mod = mod } });
return createFromConvert(store, ty, mod, kind, &convert);
try convert.initType(ty, kind, .{ .imm = .{ .set = &store.set, .zcu = zcu } });
return createFromConvert(store, ty, zcu, mod, kind, &convert);
}
fn createFromConvert(
store: *Store.Promoted,
ty: Type,
zcu: *Zcu,
mod: *Module,
kind: Kind,
convert: Convert,
) !CType {
const ip = &mod.intern_pool;
const ip = &zcu.intern_pool;
const arena = store.arena.allocator();
switch (convert.value) {
.cty => |c| return c.copy(arena),
@@ -1937,18 +1951,18 @@ pub const CType = extern union {
.packed_struct,
.packed_union,
=> {
const zig_ty_tag = ty.zigTypeTag(mod);
const zig_ty_tag = ty.zigTypeTag(zcu);
const fields_len = switch (zig_ty_tag) {
.Struct => ty.structFieldCount(mod),
.Union => mod.typeToUnion(ty).?.field_types.len,
.Struct => ty.structFieldCount(zcu),
.Union => zcu.typeToUnion(ty).?.field_types.len,
else => unreachable,
};
var c_fields_len: usize = 0;
for (0..fields_len) |field_i| {
const field_ty = ty.structFieldType(field_i, mod);
if ((zig_ty_tag == .Struct and ty.structFieldIsComptime(field_i, mod)) or
!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
const field_ty = ty.structFieldType(field_i, zcu);
if ((zig_ty_tag == .Struct and ty.structFieldIsComptime(field_i, zcu)) or
!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
c_fields_len += 1;
}
@@ -1956,26 +1970,26 @@ pub const CType = extern union {
var c_field_i: usize = 0;
for (0..fields_len) |field_i_usize| {
const field_i: u32 = @intCast(field_i_usize);
const field_ty = ty.structFieldType(field_i, mod);
if ((zig_ty_tag == .Struct and ty.structFieldIsComptime(field_i, mod)) or
!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
const field_ty = ty.structFieldType(field_i, zcu);
if ((zig_ty_tag == .Struct and ty.structFieldIsComptime(field_i, zcu)) or
!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
defer c_field_i += 1;
fields_pl[c_field_i] = .{
.name = try if (ty.isSimpleTuple(mod))
.name = try if (ty.isSimpleTuple(zcu))
std.fmt.allocPrintZ(arena, "f{}", .{field_i})
else
arena.dupeZ(u8, ip.stringToSlice(switch (zig_ty_tag) {
.Struct => ty.legacyStructFieldName(field_i, mod),
.Struct => ty.legacyStructFieldName(field_i, zcu),
.Union => ip.loadUnionType(ty.toIntern()).loadTagType(ip).names.get(ip)[field_i],
else => unreachable,
})),
.type = store.set.typeToIndex(field_ty, mod, switch (kind) {
.type = store.set.typeToIndex(field_ty, zcu, mod, switch (kind) {
.forward, .forward_parameter => .forward,
.complete, .parameter, .payload => .complete,
.global => .global,
}).?,
.alignas = AlignAs.fieldAlign(ty, field_i, mod),
.alignas = AlignAs.fieldAlign(ty, field_i, zcu),
};
}
@@ -1996,8 +2010,8 @@ pub const CType = extern union {
const unnamed_pl = try arena.create(Payload.Unnamed);
unnamed_pl.* = .{ .base = .{ .tag = t }, .data = .{
.fields = fields_pl,
.owner_decl = ty.getOwnerDecl(mod),
.id = if (ty.unionTagTypeSafety(mod)) |_| 0 else unreachable,
.owner_decl = ty.getOwnerDecl(zcu),
.id = if (ty.unionTagTypeSafety(zcu)) |_| 0 else unreachable,
} };
return initPayload(unnamed_pl);
},
@@ -2012,7 +2026,7 @@ pub const CType = extern union {
const struct_pl = try arena.create(Payload.Aggregate);
struct_pl.* = .{ .base = .{ .tag = t }, .data = .{
.fields = fields_pl,
.fwd_decl = store.set.typeToIndex(ty, mod, .forward).?,
.fwd_decl = store.set.typeToIndex(ty, zcu, mod, .forward).?,
} };
return initPayload(struct_pl);
},
@@ -2024,7 +2038,7 @@ pub const CType = extern union {
.function,
.varargs_function,
=> {
const info = mod.typeToFunc(ty).?;
const info = zcu.typeToFunc(ty).?;
assert(!info.is_generic);
const param_kind: Kind = switch (kind) {
.forward, .forward_parameter => .forward_parameter,
@@ -2034,21 +2048,21 @@ pub const CType = extern union {
var c_params_len: usize = 0;
for (info.param_types.get(ip)) |param_type| {
if (!Type.fromInterned(param_type).hasRuntimeBitsIgnoreComptime(mod)) continue;
if (!Type.fromInterned(param_type).hasRuntimeBitsIgnoreComptime(zcu)) continue;
c_params_len += 1;
}
const params_pl = try arena.alloc(Index, c_params_len);
var c_param_i: usize = 0;
for (info.param_types.get(ip)) |param_type| {
if (!Type.fromInterned(param_type).hasRuntimeBitsIgnoreComptime(mod)) continue;
params_pl[c_param_i] = store.set.typeToIndex(Type.fromInterned(param_type), mod, param_kind).?;
if (!Type.fromInterned(param_type).hasRuntimeBitsIgnoreComptime(zcu)) continue;
params_pl[c_param_i] = store.set.typeToIndex(Type.fromInterned(param_type), zcu, mod, param_kind).?;
c_param_i += 1;
}
const fn_pl = try arena.create(Payload.Function);
fn_pl.* = .{ .base = .{ .tag = t }, .data = .{
.return_type = store.set.typeToIndex(Type.fromInterned(info.return_type), mod, param_kind).?,
.return_type = store.set.typeToIndex(Type.fromInterned(info.return_type), zcu, mod, param_kind).?,
.param_types = params_pl,
} };
return initPayload(fn_pl);
@@ -2075,8 +2089,8 @@ pub const CType = extern union {
}
pub fn eql(self: @This(), ty: Type, cty: CType) bool {
const mod = self.lookup.getModule();
const ip = &mod.intern_pool;
const zcu = self.lookup.getZcu();
const ip = &zcu.intern_pool;
switch (self.convert.value) {
.cty => |c| return c.eql(cty),
.tag => |t| {
@@ -2086,24 +2100,24 @@ pub const CType = extern union {
.fwd_anon_struct,
.fwd_anon_union,
=> {
if (!ty.isTupleOrAnonStruct(mod)) return false;
if (!ty.isTupleOrAnonStruct(zcu)) return false;
var name_buf: [
std.fmt.count("f{}", .{std.math.maxInt(usize)})
]u8 = undefined;
const c_fields = cty.cast(Payload.Fields).?.data;
const zig_ty_tag = ty.zigTypeTag(mod);
const zig_ty_tag = ty.zigTypeTag(zcu);
var c_field_i: usize = 0;
for (0..switch (zig_ty_tag) {
.Struct => ty.structFieldCount(mod),
.Union => mod.typeToUnion(ty).?.field_types.len,
.Struct => ty.structFieldCount(zcu),
.Union => zcu.typeToUnion(ty).?.field_types.len,
else => unreachable,
}) |field_i_usize| {
const field_i: u32 = @intCast(field_i_usize);
const field_ty = ty.structFieldType(field_i, mod);
if ((zig_ty_tag == .Struct and ty.structFieldIsComptime(field_i, mod)) or
!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
const field_ty = ty.structFieldType(field_i, zcu);
if ((zig_ty_tag == .Struct and ty.structFieldIsComptime(field_i, zcu)) or
!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
defer c_field_i += 1;
const c_field = &c_fields[c_field_i];
@@ -2115,16 +2129,16 @@ pub const CType = extern union {
.payload => unreachable,
}) or !mem.eql(
u8,
if (ty.isSimpleTuple(mod))
if (ty.isSimpleTuple(zcu))
std.fmt.bufPrintZ(&name_buf, "f{}", .{field_i}) catch unreachable
else
ip.stringToSlice(switch (zig_ty_tag) {
.Struct => ty.legacyStructFieldName(field_i, mod),
.Struct => ty.legacyStructFieldName(field_i, zcu),
.Union => ip.loadUnionType(ty.toIntern()).loadTagType(ip).names.get(ip)[field_i],
else => unreachable,
}),
mem.span(c_field.name),
) or AlignAs.fieldAlign(ty, field_i, mod).@"align" !=
) or AlignAs.fieldAlign(ty, field_i, zcu).@"align" !=
c_field.alignas.@"align") return false;
}
return true;
@@ -2136,9 +2150,9 @@ pub const CType = extern union {
.packed_unnamed_union,
=> switch (self.kind) {
.forward, .forward_parameter, .complete, .parameter, .global => unreachable,
.payload => if (ty.unionTagTypeSafety(mod)) |_| {
.payload => if (ty.unionTagTypeSafety(zcu)) |_| {
const data = cty.cast(Payload.Unnamed).?.data;
return ty.getOwnerDecl(mod) == data.owner_decl and data.id == 0;
return ty.getOwnerDecl(zcu) == data.owner_decl and data.id == 0;
} else unreachable,
},
@@ -2157,9 +2171,9 @@ pub const CType = extern union {
.function,
.varargs_function,
=> {
if (ty.zigTypeTag(mod) != .Fn) return false;
if (ty.zigTypeTag(zcu) != .Fn) return false;
const info = mod.typeToFunc(ty).?;
const info = zcu.typeToFunc(ty).?;
assert(!info.is_generic);
const data = cty.cast(Payload.Function).?.data;
const param_kind: Kind = switch (self.kind) {
@@ -2173,7 +2187,7 @@ pub const CType = extern union {
var c_param_i: usize = 0;
for (info.param_types.get(ip)) |param_type| {
if (!Type.fromInterned(param_type).hasRuntimeBitsIgnoreComptime(mod)) continue;
if (!Type.fromInterned(param_type).hasRuntimeBitsIgnoreComptime(zcu)) continue;
if (c_param_i >= data.param_types.len) return false;
const param_cty = data.param_types[c_param_i];
@@ -2213,8 +2227,8 @@ pub const CType = extern union {
.tag => |t| {
autoHash(hasher, t);
const mod = self.lookup.getModule();
const ip = &mod.intern_pool;
const zcu = self.lookup.getZcu();
const ip = &zcu.intern_pool;
switch (t) {
.fwd_anon_struct,
.fwd_anon_union,
@@ -2223,16 +2237,16 @@ pub const CType = extern union {
std.fmt.count("f{}", .{std.math.maxInt(usize)})
]u8 = undefined;
const zig_ty_tag = ty.zigTypeTag(mod);
for (0..switch (ty.zigTypeTag(mod)) {
.Struct => ty.structFieldCount(mod),
.Union => mod.typeToUnion(ty).?.field_types.len,
const zig_ty_tag = ty.zigTypeTag(zcu);
for (0..switch (ty.zigTypeTag(zcu)) {
.Struct => ty.structFieldCount(zcu),
.Union => zcu.typeToUnion(ty).?.field_types.len,
else => unreachable,
}) |field_i_usize| {
const field_i: u32 = @intCast(field_i_usize);
const field_ty = ty.structFieldType(field_i, mod);
if ((zig_ty_tag == .Struct and ty.structFieldIsComptime(field_i, mod)) or
!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
const field_ty = ty.structFieldType(field_i, zcu);
if ((zig_ty_tag == .Struct and ty.structFieldIsComptime(field_i, zcu)) or
!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
self.updateHasherRecurse(hasher, field_ty, switch (self.kind) {
.forward, .forward_parameter => .forward,
@@ -2240,15 +2254,15 @@ pub const CType = extern union {
.global => .global,
.payload => unreachable,
});
hasher.update(if (ty.isSimpleTuple(mod))
hasher.update(if (ty.isSimpleTuple(zcu))
std.fmt.bufPrint(&name_buf, "f{}", .{field_i}) catch unreachable
else
mod.intern_pool.stringToSlice(switch (zig_ty_tag) {
.Struct => ty.legacyStructFieldName(field_i, mod),
zcu.intern_pool.stringToSlice(switch (zig_ty_tag) {
.Struct => ty.legacyStructFieldName(field_i, zcu),
.Union => ip.loadUnionType(ty.toIntern()).loadTagType(ip).names.get(ip)[field_i],
else => unreachable,
}));
autoHash(hasher, AlignAs.fieldAlign(ty, field_i, mod).@"align");
autoHash(hasher, AlignAs.fieldAlign(ty, field_i, zcu).@"align");
}
},
@@ -2258,8 +2272,8 @@ pub const CType = extern union {
.packed_unnamed_union,
=> switch (self.kind) {
.forward, .forward_parameter, .complete, .parameter, .global => unreachable,
.payload => if (ty.unionTagTypeSafety(mod)) |_| {
autoHash(hasher, ty.getOwnerDecl(mod));
.payload => if (ty.unionTagTypeSafety(zcu)) |_| {
autoHash(hasher, ty.getOwnerDecl(zcu));
autoHash(hasher, @as(u32, 0));
} else unreachable,
},
@@ -2275,7 +2289,7 @@ pub const CType = extern union {
.function,
.varargs_function,
=> {
const info = mod.typeToFunc(ty).?;
const info = zcu.typeToFunc(ty).?;
assert(!info.is_generic);
const param_kind: Kind = switch (self.kind) {
.forward, .forward_parameter => .forward_parameter,
@@ -2285,7 +2299,7 @@ pub const CType = extern union {
self.updateHasherRecurse(hasher, Type.fromInterned(info.return_type), param_kind);
for (info.param_types.get(ip)) |param_type| {
if (!Type.fromInterned(param_type).hasRuntimeBitsIgnoreComptime(mod)) continue;
if (!Type.fromInterned(param_type).hasRuntimeBitsIgnoreComptime(zcu)) continue;
self.updateHasherRecurse(hasher, Type.fromInterned(param_type), param_kind);
}
},

View File

@@ -6,7 +6,8 @@ const fs = std.fs;
const C = @This();
const build_options = @import("build_options");
const Module = @import("../Module.zig");
const Zcu = @import("../Module.zig");
const Module = @import("../Package/Module.zig");
const InternPool = @import("../InternPool.zig");
const Alignment = InternPool.Alignment;
const Compilation = @import("../Compilation.zig");
@@ -177,16 +178,16 @@ pub fn freeDecl(self: *C, decl_index: InternPool.DeclIndex) void {
pub fn updateFunc(
self: *C,
module: *Module,
zcu: *Zcu,
func_index: InternPool.Index,
air: Air,
liveness: Liveness,
) !void {
const gpa = self.base.comp.gpa;
const func = module.funcInfo(func_index);
const func = zcu.funcInfo(func_index);
const decl_index = func.owner_decl;
const decl = module.declPtr(decl_index);
const decl = zcu.declPtr(decl_index);
const gop = try self.decl_table.getOrPut(gpa, decl_index);
if (!gop.found_existing) gop.value_ptr.* = .{};
const ctypes = &gop.value_ptr.ctypes;
@@ -206,10 +207,11 @@ pub fn updateFunc(
.object = .{
.dg = .{
.gpa = gpa,
.module = module,
.zcu = zcu,
.mod = zcu.namespacePtr(decl.src_namespace).file_scope.mod,
.error_msg = null,
.pass = .{ .decl = decl_index },
.is_naked_fn = decl.typeOf(module).fnCallingConvention(module) == .Naked,
.is_naked_fn = decl.typeOf(zcu).fnCallingConvention(zcu) == .Naked,
.fwd_decl = fwd_decl.toManaged(gpa),
.ctypes = ctypes.*,
.anon_decl_deps = self.anon_decls,
@@ -232,7 +234,7 @@ pub fn updateFunc(
codegen.genFunc(&function) catch |err| switch (err) {
error.AnalysisFail => {
try module.failed_decls.put(gpa, decl_index, function.object.dg.error_msg.?);
try zcu.failed_decls.put(gpa, decl_index, function.object.dg.error_msg.?);
return;
},
else => |e| return e,
@@ -249,7 +251,7 @@ pub fn updateFunc(
gop.value_ptr.fwd_decl = try self.addString(function.object.dg.fwd_decl.items);
}
fn updateAnonDecl(self: *C, module: *Module, i: usize) !void {
fn updateAnonDecl(self: *C, zcu: *Zcu, i: usize) !void {
const gpa = self.base.comp.gpa;
const anon_decl = self.anon_decls.keys()[i];
@@ -261,7 +263,8 @@ fn updateAnonDecl(self: *C, module: *Module, i: usize) !void {
var object: codegen.Object = .{
.dg = .{
.gpa = gpa,
.module = module,
.zcu = zcu,
.mod = zcu.root_mod,
.error_msg = null,
.pass = .{ .anon = anon_decl },
.is_naked_fn = false,
@@ -283,12 +286,12 @@ fn updateAnonDecl(self: *C, module: *Module, i: usize) !void {
code.* = object.code.moveToUnmanaged();
}
const c_value: codegen.CValue = .{ .constant = anon_decl };
const c_value: codegen.CValue = .{ .constant = Value.fromInterned(anon_decl) };
const alignment: Alignment = self.aligned_anon_decls.get(anon_decl) orelse .none;
codegen.genDeclValue(&object, Value.fromInterned(anon_decl), false, c_value, alignment, .none) catch |err| switch (err) {
codegen.genDeclValue(&object, c_value.constant, false, c_value, alignment, .none) catch |err| switch (err) {
error.AnalysisFail => {
@panic("TODO: C backend AnalysisFail on anonymous decl");
//try module.failed_decls.put(gpa, decl_index, object.dg.error_msg.?);
//try zcu.failed_decls.put(gpa, decl_index, object.dg.error_msg.?);
//return;
},
else => |e| return e,
@@ -304,12 +307,13 @@ fn updateAnonDecl(self: *C, module: *Module, i: usize) !void {
};
}
pub fn updateDecl(self: *C, module: *Module, decl_index: InternPool.DeclIndex) !void {
pub fn updateDecl(self: *C, zcu: *Zcu, decl_index: InternPool.DeclIndex) !void {
const tracy = trace(@src());
defer tracy.end();
const gpa = self.base.comp.gpa;
const decl = zcu.declPtr(decl_index);
const gop = try self.decl_table.getOrPut(gpa, decl_index);
if (!gop.found_existing) {
gop.value_ptr.* = .{};
@@ -324,7 +328,8 @@ pub fn updateDecl(self: *C, module: *Module, decl_index: InternPool.DeclIndex) !
var object: codegen.Object = .{
.dg = .{
.gpa = gpa,
.module = module,
.zcu = zcu,
.mod = zcu.namespacePtr(decl.src_namespace).file_scope.mod,
.error_msg = null,
.pass = .{ .decl = decl_index },
.is_naked_fn = false,
@@ -347,7 +352,7 @@ pub fn updateDecl(self: *C, module: *Module, decl_index: InternPool.DeclIndex) !
codegen.genDecl(&object) catch |err| switch (err) {
error.AnalysisFail => {
try module.failed_decls.put(gpa, decl_index, object.dg.error_msg.?);
try zcu.failed_decls.put(gpa, decl_index, object.dg.error_msg.?);
return;
},
else => |e| return e,
@@ -362,11 +367,11 @@ pub fn updateDecl(self: *C, module: *Module, decl_index: InternPool.DeclIndex) !
gop.value_ptr.fwd_decl = try self.addString(object.dg.fwd_decl.items);
}
pub fn updateDeclLineNumber(self: *C, module: *Module, decl_index: InternPool.DeclIndex) !void {
pub fn updateDeclLineNumber(self: *C, zcu: *Zcu, decl_index: InternPool.DeclIndex) !void {
// The C backend does not have the ability to fix line numbers without re-generating
// the entire Decl.
_ = self;
_ = module;
_ = zcu;
_ = decl_index;
}
@@ -399,12 +404,12 @@ pub fn flushModule(self: *C, arena: Allocator, prog_node: *std.Progress.Node) !v
const comp = self.base.comp;
const gpa = comp.gpa;
const module = self.base.comp.module.?;
const zcu = self.base.comp.module.?;
{
var i: usize = 0;
while (i < self.anon_decls.count()) : (i += 1) {
try updateAnonDecl(self, module, i);
try updateAnonDecl(self, zcu, i);
}
}
@@ -414,7 +419,7 @@ pub fn flushModule(self: *C, arena: Allocator, prog_node: *std.Progress.Node) !v
var f: Flush = .{};
defer f.deinit(gpa);
const abi_defines = try self.abiDefines(module.getTarget());
const abi_defines = try self.abiDefines(zcu.getTarget());
defer abi_defines.deinit();
// Covers defines, zig.h, ctypes, asm, lazy fwd.
@@ -429,7 +434,7 @@ pub fn flushModule(self: *C, arena: Allocator, prog_node: *std.Progress.Node) !v
{
var asm_buf = f.asm_buf.toManaged(gpa);
defer f.asm_buf = asm_buf.moveToUnmanaged();
try codegen.genGlobalAsm(module, asm_buf.writer());
try codegen.genGlobalAsm(zcu, asm_buf.writer());
f.appendBufAssumeCapacity(asm_buf.items);
}
@@ -438,7 +443,7 @@ pub fn flushModule(self: *C, arena: Allocator, prog_node: *std.Progress.Node) !v
self.lazy_fwd_decl_buf.clearRetainingCapacity();
self.lazy_code_buf.clearRetainingCapacity();
try self.flushErrDecls(&f.lazy_ctypes);
try self.flushErrDecls(zcu, &f.lazy_ctypes);
// Unlike other backends, the .c code we are emitting has order-dependent decls.
// `CType`s, forward decls, and non-functions first.
@@ -446,19 +451,20 @@ pub fn flushModule(self: *C, arena: Allocator, prog_node: *std.Progress.Node) !v
{
var export_names: std.AutoHashMapUnmanaged(InternPool.NullTerminatedString, void) = .{};
defer export_names.deinit(gpa);
try export_names.ensureTotalCapacity(gpa, @intCast(module.decl_exports.entries.len));
for (module.decl_exports.values()) |exports| for (exports.items) |@"export"|
try export_names.ensureTotalCapacity(gpa, @intCast(zcu.decl_exports.entries.len));
for (zcu.decl_exports.values()) |exports| for (exports.items) |@"export"|
try export_names.put(gpa, @"export".opts.name, {});
for (self.anon_decls.values()) |*decl_block| {
try self.flushDeclBlock(&f, decl_block, export_names, .none);
try self.flushDeclBlock(zcu, zcu.root_mod, &f, decl_block, export_names, .none);
}
for (self.decl_table.keys(), self.decl_table.values()) |decl_index, *decl_block| {
assert(module.declPtr(decl_index).has_tv);
const decl = module.declPtr(decl_index);
const extern_symbol_name = if (decl.isExtern(module)) decl.name.toOptional() else .none;
try self.flushDeclBlock(&f, decl_block, export_names, extern_symbol_name);
const decl = zcu.declPtr(decl_index);
assert(decl.has_tv);
const extern_symbol_name = if (decl.isExtern(zcu)) decl.name.toOptional() else .none;
const mod = zcu.namespacePtr(decl.src_namespace).file_scope.mod;
try self.flushDeclBlock(zcu, mod, &f, decl_block, export_names, extern_symbol_name);
}
}
@@ -466,14 +472,14 @@ pub fn flushModule(self: *C, arena: Allocator, prog_node: *std.Progress.Node) !v
// We need to flush lazy ctypes after flushing all decls but before flushing any decl ctypes.
// This ensures that every lazy CType.Index exactly matches the global CType.Index.
assert(f.ctypes.count() == 0);
try self.flushCTypes(&f, .flush, f.lazy_ctypes);
try self.flushCTypes(zcu, &f, .flush, f.lazy_ctypes);
for (self.anon_decls.keys(), self.anon_decls.values()) |anon_decl, decl_block| {
try self.flushCTypes(&f, .{ .anon = anon_decl }, decl_block.ctypes);
try self.flushCTypes(zcu, &f, .{ .anon = anon_decl }, decl_block.ctypes);
}
for (self.decl_table.keys(), self.decl_table.values()) |decl_index, decl_block| {
try self.flushCTypes(&f, .{ .decl = decl_index }, decl_block.ctypes);
try self.flushCTypes(zcu, &f, .{ .decl = decl_index }, decl_block.ctypes);
}
}
@@ -543,12 +549,12 @@ const FlushDeclError = error{
fn flushCTypes(
self: *C,
zcu: *Zcu,
f: *Flush,
pass: codegen.DeclGen.Pass,
decl_ctypes: codegen.CType.Store,
) FlushDeclError!void {
const gpa = self.base.comp.gpa;
const mod = self.base.comp.module.?;
const decl_ctypes_len = decl_ctypes.count();
f.ctypes_map.clearRetainingCapacity();
@@ -615,7 +621,7 @@ fn flushCTypes(
assert(decl_cty.hash(decl_ctypes.set) == global_cty.hash(global_ctypes.set));
}
try codegen.genTypeDecl(
mod,
zcu,
writer,
global_ctypes.set,
global_idx,
@@ -627,7 +633,7 @@ fn flushCTypes(
}
}
fn flushErrDecls(self: *C, ctypes: *codegen.CType.Store) FlushDeclError!void {
fn flushErrDecls(self: *C, zcu: *Zcu, ctypes: *codegen.CType.Store) FlushDeclError!void {
const gpa = self.base.comp.gpa;
const fwd_decl = &self.lazy_fwd_decl_buf;
@@ -636,7 +642,8 @@ fn flushErrDecls(self: *C, ctypes: *codegen.CType.Store) FlushDeclError!void {
var object = codegen.Object{
.dg = .{
.gpa = gpa,
.module = self.base.comp.module.?,
.zcu = zcu,
.mod = zcu.root_mod,
.error_msg = null,
.pass = .flush,
.is_naked_fn = false,
@@ -667,6 +674,8 @@ fn flushErrDecls(self: *C, ctypes: *codegen.CType.Store) FlushDeclError!void {
fn flushLazyFn(
self: *C,
zcu: *Zcu,
mod: *Module,
ctypes: *codegen.CType.Store,
lazy_fn: codegen.LazyFnMap.Entry,
) FlushDeclError!void {
@@ -678,7 +687,8 @@ fn flushLazyFn(
var object = codegen.Object{
.dg = .{
.gpa = gpa,
.module = self.base.comp.module.?,
.zcu = zcu,
.mod = mod,
.error_msg = null,
.pass = .flush,
.is_naked_fn = false,
@@ -709,7 +719,13 @@ fn flushLazyFn(
ctypes.* = object.dg.ctypes.move();
}
fn flushLazyFns(self: *C, f: *Flush, lazy_fns: codegen.LazyFnMap) FlushDeclError!void {
fn flushLazyFns(
self: *C,
zcu: *Zcu,
mod: *Module,
f: *Flush,
lazy_fns: codegen.LazyFnMap,
) FlushDeclError!void {
const gpa = self.base.comp.gpa;
try f.lazy_fns.ensureUnusedCapacity(gpa, @intCast(lazy_fns.count()));
@@ -718,19 +734,21 @@ fn flushLazyFns(self: *C, f: *Flush, lazy_fns: codegen.LazyFnMap) FlushDeclError
const gop = f.lazy_fns.getOrPutAssumeCapacity(entry.key_ptr.*);
if (gop.found_existing) continue;
gop.value_ptr.* = {};
try self.flushLazyFn(&f.lazy_ctypes, entry);
try self.flushLazyFn(zcu, mod, &f.lazy_ctypes, entry);
}
}
fn flushDeclBlock(
self: *C,
zcu: *Zcu,
mod: *Module,
f: *Flush,
decl_block: *DeclBlock,
export_names: std.AutoHashMapUnmanaged(InternPool.NullTerminatedString, void),
extern_symbol_name: InternPool.OptionalNullTerminatedString,
) FlushDeclError!void {
const gpa = self.base.comp.gpa;
try self.flushLazyFns(f, decl_block.lazy_fns);
try self.flushLazyFns(zcu, mod, f, decl_block.lazy_fns);
try f.all_buffers.ensureUnusedCapacity(gpa, 1);
fwd_decl: {
if (extern_symbol_name.unwrap()) |name| {
@@ -740,15 +758,15 @@ fn flushDeclBlock(
}
}
pub fn flushEmitH(module: *Module) !void {
pub fn flushEmitH(zcu: *Zcu) !void {
const tracy = trace(@src());
defer tracy.end();
const emit_h = module.emit_h orelse return;
const emit_h = zcu.emit_h orelse return;
// We collect a list of buffers to write, and write them all at once with pwritev 😎
const num_buffers = emit_h.decl_table.count() + 1;
var all_buffers = try std.ArrayList(std.posix.iovec_const).initCapacity(module.gpa, num_buffers);
var all_buffers = try std.ArrayList(std.posix.iovec_const).initCapacity(zcu.gpa, num_buffers);
defer all_buffers.deinit();
var file_size: u64 = zig_h.len;
@@ -771,7 +789,7 @@ pub fn flushEmitH(module: *Module) !void {
}
}
const directory = emit_h.loc.directory orelse module.comp.local_cache_directory;
const directory = emit_h.loc.directory orelse zcu.comp.local_cache_directory;
const file = try directory.handle.createFile(emit_h.loc.basename, .{
// We set the end position explicitly below; by not truncating the file, we possibly
// make it easier on the file system by doing 1 reallocation instead of two.
@@ -785,12 +803,12 @@ pub fn flushEmitH(module: *Module) !void {
pub fn updateExports(
self: *C,
module: *Module,
exported: Module.Exported,
exports: []const *Module.Export,
zcu: *Zcu,
exported: Zcu.Exported,
exports: []const *Zcu.Export,
) !void {
_ = exports;
_ = exported;
_ = module;
_ = zcu;
_ = self;
}