@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
2459
src/codegen/c.zig
2459
src/codegen/c.zig
File diff suppressed because it is too large
Load Diff
@@ -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);
|
||||
}
|
||||
},
|
||||
|
||||
114
src/link/C.zig
114
src/link/C.zig
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user