Commit 6f10b11658
Changed files (5)
lib
src
lib/zig.h
@@ -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)
src/codegen/c/type.zig
@@ -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);
}
},
src/codegen/c.zig
@@ -5,12 +5,13 @@ const mem = std.mem;
const log = std.log.scoped(.c);
const link = @import("../link.zig");
-const Module = @import("../Module.zig");
+const Zcu = @import("../Module.zig");
+const Module = @import("../Package/Module.zig");
const Compilation = @import("../Compilation.zig");
const Value = @import("../Value.zig");
const Type = @import("../type.zig").Type;
const C = link.File.C;
-const Decl = Module.Decl;
+const Decl = Zcu.Decl;
const trace = @import("../tracy.zig").trace;
const LazySrcLoc = std.zig.LazySrcLoc;
const Air = @import("../Air.zig");
@@ -30,7 +31,7 @@ pub const CValue = union(enum) {
/// Address of a local.
local_ref: LocalIndex,
/// A constant instruction, to be rendered inline.
- constant: InternPool.Index,
+ constant: Value,
/// Index into the parameters
arg: usize,
/// The array field of a parameter
@@ -72,13 +73,15 @@ pub const LazyFnValue = struct {
};
pub const LazyFnMap = std.AutoArrayHashMapUnmanaged(LazyFnKey, LazyFnValue);
-const LoopDepth = u16;
const Local = struct {
cty_idx: CType.Index,
- alignas: CType.AlignAs,
+ flags: packed struct(u32) {
+ alignas: CType.AlignAs,
+ _: u20 = undefined,
+ },
pub fn getType(local: Local) LocalType {
- return .{ .cty_idx = local.cty_idx, .alignas = local.alignas };
+ return .{ .cty_idx = local.cty_idx, .alignas = local.flags.alignas };
}
};
@@ -300,11 +303,11 @@ pub const Function = struct {
const gop = try f.value_map.getOrPut(ref);
if (gop.found_existing) return gop.value_ptr.*;
- const mod = f.object.dg.module;
- const val = (try f.air.value(ref, mod)).?;
+ const zcu = f.object.dg.zcu;
+ const val = (try f.air.value(ref, zcu)).?;
const ty = f.typeOf(ref);
- const result: CValue = if (lowersToArray(ty, mod)) result: {
+ const result: CValue = if (lowersToArray(ty, zcu)) result: {
const writer = f.object.codeHeaderWriter();
const alignment: Alignment = .none;
const decl_c_value = try f.allocLocalValue(ty, alignment);
@@ -313,17 +316,17 @@ pub const Function = struct {
try writer.writeAll("static ");
try f.object.dg.renderTypeAndName(writer, ty, decl_c_value, Const, alignment, .complete);
try writer.writeAll(" = ");
- try f.object.dg.renderValue(writer, ty, val, .StaticInitializer);
+ try f.object.dg.renderValue(writer, val, .StaticInitializer);
try writer.writeAll(";\n ");
break :result decl_c_value;
- } else .{ .constant = val.toIntern() };
+ } else .{ .constant = val };
gop.value_ptr.* = result;
return result;
}
fn wantSafety(f: *Function) bool {
- return switch (f.object.dg.module.optimizeMode()) {
+ return switch (f.object.dg.zcu.optimizeMode()) {
.Debug, .ReleaseSafe => true,
.ReleaseFast, .ReleaseSmall => false,
};
@@ -333,11 +336,13 @@ pub const Function = struct {
/// those which go into `allocs`. This function does not add the resulting local into `allocs`;
/// that responsibility lies with the caller.
fn allocLocalValue(f: *Function, ty: Type, alignment: Alignment) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const gpa = f.object.dg.gpa;
try f.locals.append(gpa, .{
.cty_idx = try f.typeToIndex(ty, .complete),
- .alignas = CType.AlignAs.init(alignment, ty.abiAlignment(mod)),
+ .flags = .{
+ .alignas = CType.AlignAs.init(alignment, ty.abiAlignment(zcu)),
+ },
});
return .{ .new_local = @intCast(f.locals.items.len - 1) };
}
@@ -355,79 +360,100 @@ pub const Function = struct {
/// Only allocates the local; does not print anything. Will attempt to re-use locals, so should
/// not be used for persistent locals (i.e. those in `allocs`).
fn allocAlignedLocal(f: *Function, ty: Type, _: CQualifiers, alignment: Alignment) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
if (f.free_locals_map.getPtr(.{
.cty_idx = try f.typeToIndex(ty, .complete),
- .alignas = CType.AlignAs.init(alignment, ty.abiAlignment(mod)),
+ .alignas = CType.AlignAs.init(alignment, ty.abiAlignment(zcu)),
})) |locals_list| {
if (locals_list.popOrNull()) |local_entry| {
return .{ .new_local = local_entry.key };
}
}
- return try f.allocLocalValue(ty, alignment);
+ return f.allocLocalValue(ty, alignment);
}
fn writeCValue(f: *Function, w: anytype, c_value: CValue, location: ValueRenderLocation) !void {
switch (c_value) {
- .constant => |val| try f.object.dg.renderValue(
- w,
- Type.fromInterned(f.object.dg.module.intern_pool.typeOf(val)),
- Value.fromInterned(val),
- location,
- ),
- .undef => |ty| try f.object.dg.renderValue(w, ty, Value.undef, location),
+ .none => unreachable,
+ .new_local, .local => |i| try w.print("t{d}", .{i}),
+ .local_ref => |i| {
+ const local = &f.locals.items[i];
+ if (local.flags.alignas.abiOrder().compare(.lt)) {
+ const zcu = f.object.dg.zcu;
+ const pointee_ty = try zcu.intType(.unsigned, @min(
+ local.flags.alignas.@"align".toByteUnitsOptional().?,
+ f.object.dg.mod.resolved_target.result.maxIntAlignment(),
+ ) * 8);
+ const ptr_ty = try zcu.singleMutPtrType(pointee_ty);
+
+ try w.writeByte('(');
+ try f.renderType(w, ptr_ty);
+ try w.writeByte(')');
+ }
+ try w.print("&t{d}", .{i});
+ },
+ .constant => |val| try f.object.dg.renderValue(w, val, location),
+ .arg => |i| try w.print("a{d}", .{i}),
+ .arg_array => |i| try f.writeCValueMember(w, .{ .arg = i }, .{ .identifier = "array" }),
+ .undef => |ty| try f.object.dg.renderUndefValue(w, ty, location),
else => try f.object.dg.writeCValue(w, c_value),
}
}
fn writeCValueDeref(f: *Function, w: anytype, c_value: CValue) !void {
switch (c_value) {
- .constant => |val| {
+ .none => unreachable,
+ .new_local, .local, .constant => {
try w.writeAll("(*");
- try f.object.dg.renderValue(
- w,
- Type.fromInterned(f.object.dg.module.intern_pool.typeOf(val)),
- Value.fromInterned(val),
- .Other,
- );
+ try f.writeCValue(w, c_value, .Other);
+ try w.writeByte(')');
+ },
+ .local_ref => |i| try w.print("t{d}", .{i}),
+ .arg => |i| try w.print("(*a{d})", .{i}),
+ .arg_array => |i| {
+ try w.writeAll("(*");
+ try f.writeCValueMember(w, .{ .arg = i }, .{ .identifier = "array" });
try w.writeByte(')');
},
else => try f.object.dg.writeCValueDeref(w, c_value),
}
}
- fn writeCValueMember(f: *Function, w: anytype, c_value: CValue, member: CValue) !void {
+ fn writeCValueMember(
+ f: *Function,
+ writer: anytype,
+ c_value: CValue,
+ member: CValue,
+ ) error{ OutOfMemory, AnalysisFail }!void {
switch (c_value) {
- .constant => |val| {
- try f.object.dg.renderValue(
- w,
- Type.fromInterned(f.object.dg.module.intern_pool.typeOf(val)),
- Value.fromInterned(val),
- .Other,
- );
- try w.writeByte('.');
- try f.writeCValue(w, member, .Other);
+ .new_local, .local, .local_ref, .constant, .arg, .arg_array => {
+ try f.writeCValue(writer, c_value, .Other);
+ try writer.writeByte('.');
+ try f.writeCValue(writer, member, .Other);
},
- else => try f.object.dg.writeCValueMember(w, c_value, member),
+ else => return f.object.dg.writeCValueMember(writer, c_value, member),
}
}
- fn writeCValueDerefMember(f: *Function, w: anytype, c_value: CValue, member: CValue) !void {
+ fn writeCValueDerefMember(f: *Function, writer: anytype, c_value: CValue, member: CValue) !void {
switch (c_value) {
- .constant => |val| {
- try w.writeByte('(');
- try f.object.dg.renderValue(
- w,
- Type.fromInterned(f.object.dg.module.intern_pool.typeOf(val)),
- Value.fromInterned(val),
- .Other,
- );
- try w.writeAll(")->");
- try f.writeCValue(w, member, .Other);
+ .new_local, .local, .arg, .arg_array => {
+ try f.writeCValue(writer, c_value, .Other);
+ try writer.writeAll("->");
+ },
+ .constant => {
+ try writer.writeByte('(');
+ try f.writeCValue(writer, c_value, .Other);
+ try writer.writeAll(")->");
+ },
+ .local_ref => {
+ try f.writeCValueDeref(writer, c_value);
+ try writer.writeByte('.');
},
- else => try f.object.dg.writeCValueDerefMember(w, c_value, member),
+ else => return f.object.dg.writeCValueDerefMember(writer, c_value, member),
}
+ try f.writeCValue(writer, member, .Other);
}
fn fail(f: *Function, comptime format: []const u8, args: anytype) error{ AnalysisFail, OutOfMemory } {
@@ -462,8 +488,8 @@ pub const Function = struct {
return f.object.dg.renderIntCast(w, dest_ty, .{ .c_value = .{ .f = f, .value = src, .v = v } }, src_ty, location);
}
- fn fmtIntLiteral(f: *Function, ty: Type, val: Value) !std.fmt.Formatter(formatIntLiteral) {
- return f.object.dg.fmtIntLiteral(ty, val, .Other);
+ fn fmtIntLiteral(f: *Function, val: Value) !std.fmt.Formatter(formatIntLiteral) {
+ return f.object.dg.fmtIntLiteral(val, .Other);
}
fn getLazyFnName(f: *Function, key: LazyFnKey, data: LazyFnValue.Data) ![]const u8 {
@@ -475,7 +501,7 @@ pub const Function = struct {
var promoted = f.object.dg.ctypes.promote(gpa);
defer f.object.dg.ctypes.demote(promoted);
const arena = promoted.arena.allocator();
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
gop.value_ptr.* = .{
.fn_name = switch (key) {
@@ -484,7 +510,7 @@ pub const Function = struct {
.never_inline,
=> |owner_decl| try std.fmt.allocPrint(arena, "zig_{s}_{}__{d}", .{
@tagName(key),
- fmtIdent(mod.intern_pool.stringToSlice(mod.declPtr(owner_decl).name)),
+ fmtIdent(zcu.intern_pool.stringToSlice(zcu.declPtr(owner_decl).name)),
@intFromEnum(owner_decl),
}),
},
@@ -510,17 +536,17 @@ pub const Function = struct {
}
fn typeOf(f: *Function, inst: Air.Inst.Ref) Type {
- const mod = f.object.dg.module;
- return f.air.typeOf(inst, &mod.intern_pool);
+ const zcu = f.object.dg.zcu;
+ return f.air.typeOf(inst, &zcu.intern_pool);
}
fn typeOfIndex(f: *Function, inst: Air.Inst.Index) Type {
- const mod = f.object.dg.module;
- return f.air.typeOfIndex(inst, &mod.intern_pool);
+ const zcu = f.object.dg.zcu;
+ return f.air.typeOfIndex(inst, &zcu.intern_pool);
}
};
-/// This data is available when outputting .c code for a `Module`.
+/// This data is available when outputting .c code for a `Zcu`.
/// It is not available when generating .h file.
pub const Object = struct {
dg: DeclGen,
@@ -542,12 +568,13 @@ pub const Object = struct {
/// This data is available both when outputting .c code and when outputting an .h file.
pub const DeclGen = struct {
gpa: mem.Allocator,
- module: *Module,
+ zcu: *Zcu,
+ mod: *Module,
pass: Pass,
is_naked_fn: bool,
/// This is a borrowed reference from `link.C`.
fwd_decl: std.ArrayList(u8),
- error_msg: ?*Module.ErrorMsg,
+ error_msg: ?*Zcu.ErrorMsg,
ctypes: CType.Store,
/// Keeps track of anonymous decls that need to be rendered before this
/// (named) Decl in the output C code.
@@ -566,75 +593,70 @@ pub const DeclGen = struct {
fn fail(dg: *DeclGen, comptime format: []const u8, args: anytype) error{ AnalysisFail, OutOfMemory } {
@setCold(true);
- const mod = dg.module;
+ const zcu = dg.zcu;
const decl_index = dg.pass.decl;
- const decl = mod.declPtr(decl_index);
- const src_loc = decl.srcLoc(mod);
- dg.error_msg = try Module.ErrorMsg.create(dg.gpa, src_loc, format, args);
+ const decl = zcu.declPtr(decl_index);
+ const src_loc = decl.srcLoc(zcu);
+ dg.error_msg = try Zcu.ErrorMsg.create(dg.gpa, src_loc, format, args);
return error.AnalysisFail;
}
fn renderAnonDeclValue(
dg: *DeclGen,
writer: anytype,
- ty: Type,
ptr_val: Value,
anon_decl: InternPool.Key.Ptr.Addr.AnonDecl,
location: ValueRenderLocation,
) error{ OutOfMemory, AnalysisFail }!void {
- const mod = dg.module;
- const ip = &mod.intern_pool;
- const decl_val = anon_decl.val;
- const decl_ty = Type.fromInterned(ip.typeOf(decl_val));
+ const zcu = dg.zcu;
+ const ip = &zcu.intern_pool;
+ const decl_val = Value.fromInterned(anon_decl.val);
+ const decl_ty = decl_val.typeOf(zcu);
// Render an undefined pointer if we have a pointer to a zero-bit or comptime type.
- if (ty.isPtrAtRuntime(mod) and !decl_ty.isFnOrHasRuntimeBits(mod)) {
- return dg.writeCValue(writer, .{ .undef = ty });
+ const ptr_ty = ptr_val.typeOf(zcu);
+ if (ptr_ty.isPtrAtRuntime(zcu) and !decl_ty.isFnOrHasRuntimeBits(zcu)) {
+ return dg.writeCValue(writer, .{ .undef = ptr_ty });
}
// Chase function values in order to be able to reference the original function.
- if (Value.fromInterned(decl_val).getFunction(mod)) |func| {
- _ = func;
- _ = ptr_val;
- _ = location;
- @panic("TODO");
- }
- if (Value.fromInterned(decl_val).getExternFunc(mod)) |extern_func| {
- _ = extern_func;
- _ = ptr_val;
- _ = location;
- @panic("TODO");
- }
+ if (decl_val.getFunction(zcu)) |func|
+ return dg.renderDeclValue(writer, ptr_val, func.owner_decl, location);
+ if (decl_val.getExternFunc(zcu)) |extern_func|
+ return dg.renderDeclValue(writer, ptr_val, extern_func.decl, location);
- assert(Value.fromInterned(decl_val).getVariable(mod) == null);
+ assert(decl_val.getVariable(zcu) == null);
// We shouldn't cast C function pointers as this is UB (when you call
// them). The analysis until now should ensure that the C function
// pointers are compatible. If they are not, then there is a bug
// somewhere and we should let the C compiler tell us about it.
- const need_typecast = if (ty.castPtrToFn(mod)) |_| false else !ty.childType(mod).eql(decl_ty, mod);
- if (need_typecast) {
+ const child_cty = (try dg.typeToCType(ptr_ty, .complete)).cast(CType.Payload.Child).?.data;
+ const decl_cty = try dg.typeToIndex(decl_ty, .complete);
+ const need_cast = child_cty != decl_cty and
+ (dg.indexToCType(child_cty).tag() != .function or dg.indexToCType(decl_cty).tag() != .function);
+ if (need_cast) {
try writer.writeAll("((");
- try dg.renderType(writer, ty);
+ try dg.renderType(writer, ptr_ty);
try writer.writeByte(')');
}
try writer.writeByte('&');
try renderAnonDeclName(writer, decl_val);
- if (need_typecast) try writer.writeByte(')');
+ if (need_cast) try writer.writeByte(')');
// Indicate that the anon decl should be rendered to the output so that
// our reference above is not undefined.
const ptr_type = ip.indexToKey(anon_decl.orig_ty).ptr_type;
- const gop = try dg.anon_decl_deps.getOrPut(dg.gpa, decl_val);
+ const gop = try dg.anon_decl_deps.getOrPut(dg.gpa, anon_decl.val);
if (!gop.found_existing) gop.value_ptr.* = .{};
// Only insert an alignment entry if the alignment is greater than ABI
// alignment. If there is already an entry, keep the greater alignment.
const explicit_alignment = ptr_type.flags.alignment;
if (explicit_alignment != .none) {
- const abi_alignment = Type.fromInterned(ptr_type.child).abiAlignment(mod);
+ const abi_alignment = Type.fromInterned(ptr_type.child).abiAlignment(zcu);
if (explicit_alignment.compareStrict(.gt, abi_alignment)) {
- const aligned_gop = try dg.aligned_anon_decls.getOrPut(dg.gpa, decl_val);
+ const aligned_gop = try dg.aligned_anon_decls.getOrPut(dg.gpa, anon_decl.val);
aligned_gop.value_ptr.* = if (aligned_gop.found_existing)
aligned_gop.value_ptr.maxStrict(explicit_alignment)
else
@@ -646,41 +668,45 @@ pub const DeclGen = struct {
fn renderDeclValue(
dg: *DeclGen,
writer: anytype,
- ty: Type,
val: Value,
decl_index: InternPool.DeclIndex,
location: ValueRenderLocation,
) error{ OutOfMemory, AnalysisFail }!void {
- const mod = dg.module;
- const decl = mod.declPtr(decl_index);
+ const zcu = dg.zcu;
+ const decl = zcu.declPtr(decl_index);
assert(decl.has_tv);
// Render an undefined pointer if we have a pointer to a zero-bit or comptime type.
- if (ty.isPtrAtRuntime(mod) and !decl.typeOf(mod).isFnOrHasRuntimeBits(mod)) {
+ const ty = val.typeOf(zcu);
+ const decl_ty = decl.typeOf(zcu);
+ if (ty.isPtrAtRuntime(zcu) and !decl_ty.isFnOrHasRuntimeBits(zcu)) {
return dg.writeCValue(writer, .{ .undef = ty });
}
// Chase function values in order to be able to reference the original function.
- if (decl.val.getFunction(mod)) |func| if (func.owner_decl != decl_index)
- return dg.renderDeclValue(writer, ty, val, func.owner_decl, location);
- if (decl.val.getExternFunc(mod)) |extern_func| if (extern_func.decl != decl_index)
- return dg.renderDeclValue(writer, ty, val, extern_func.decl, location);
+ if (decl.val.getFunction(zcu)) |func| if (func.owner_decl != decl_index)
+ return dg.renderDeclValue(writer, val, func.owner_decl, location);
+ if (decl.val.getExternFunc(zcu)) |extern_func| if (extern_func.decl != decl_index)
+ return dg.renderDeclValue(writer, val, extern_func.decl, location);
- if (decl.val.getVariable(mod)) |variable| try dg.renderFwdDecl(decl_index, variable, .tentative);
+ if (decl.val.getVariable(zcu)) |variable| try dg.renderFwdDecl(decl_index, variable, .tentative);
// We shouldn't cast C function pointers as this is UB (when you call
// them). The analysis until now should ensure that the C function
// pointers are compatible. If they are not, then there is a bug
// somewhere and we should let the C compiler tell us about it.
- const need_typecast = if (ty.castPtrToFn(mod)) |_| false else !ty.childType(mod).eql(decl.typeOf(mod), mod);
- if (need_typecast) {
+ const child_cty = (try dg.typeToCType(ty, .complete)).cast(CType.Payload.Child).?.data;
+ const decl_cty = try dg.typeToIndex(decl_ty, .complete);
+ const need_cast = child_cty != decl_cty and
+ (dg.indexToCType(child_cty).tag() != .function or dg.indexToCType(decl_cty).tag() != .function);
+ if (need_cast) {
try writer.writeAll("((");
try dg.renderType(writer, ty);
try writer.writeByte(')');
}
try writer.writeByte('&');
try dg.renderDeclName(writer, decl_index, 0);
- if (need_typecast) try writer.writeByte(')');
+ if (need_cast) try writer.writeByte(')');
}
/// Renders a "parent" pointer by recursing to the root decl/variable
@@ -691,31 +717,32 @@ pub const DeclGen = struct {
ptr_val: InternPool.Index,
location: ValueRenderLocation,
) error{ OutOfMemory, AnalysisFail }!void {
- const mod = dg.module;
- const ptr_ty = Type.fromInterned(mod.intern_pool.typeOf(ptr_val));
+ const zcu = dg.zcu;
+ const ip = &zcu.intern_pool;
+ const ptr_ty = Type.fromInterned(ip.typeOf(ptr_val));
const ptr_cty = try dg.typeToIndex(ptr_ty, .complete);
- const ptr = mod.intern_pool.indexToKey(ptr_val).ptr;
+ const ptr_child_cty = dg.indexToCType(ptr_cty).cast(CType.Payload.Child).?.data;
+ const ptr = ip.indexToKey(ptr_val).ptr;
switch (ptr.addr) {
- .decl => |d| try dg.renderDeclValue(writer, ptr_ty, Value.fromInterned(ptr_val), d, location),
- .anon_decl => |anon_decl| try dg.renderAnonDeclValue(writer, ptr_ty, Value.fromInterned(ptr_val), anon_decl, location),
+ .decl => |d| try dg.renderDeclValue(writer, Value.fromInterned(ptr_val), d, location),
+ .anon_decl => |anon_decl| try dg.renderAnonDeclValue(writer, Value.fromInterned(ptr_val), anon_decl, location),
.int => |int| {
try writer.writeByte('(');
try dg.renderCType(writer, ptr_cty);
- try writer.print("){x}", .{try dg.fmtIntLiteral(Type.usize, Value.fromInterned(int), .Other)});
+ try writer.print("){x}", .{try dg.fmtIntLiteral(Value.fromInterned(int), .Other)});
},
.eu_payload, .opt_payload => |base| {
- const ptr_base_ty = Type.fromInterned(mod.intern_pool.typeOf(base));
- const base_ty = ptr_base_ty.childType(mod);
+ const ptr_base_ty = Type.fromInterned(ip.typeOf(base));
+ const base_ty = ptr_base_ty.childType(zcu);
// Ensure complete type definition is visible before accessing fields.
_ = try dg.typeToIndex(base_ty, .complete);
const payload_ty = switch (ptr.addr) {
- .eu_payload => base_ty.errorUnionPayload(mod),
- .opt_payload => base_ty.optionalChild(mod),
+ .eu_payload => base_ty.errorUnionPayload(zcu),
+ .opt_payload => base_ty.optionalChild(zcu),
else => unreachable,
};
- const ptr_payload_ty = try mod.adjustPtrTypeChild(ptr_base_ty, payload_ty);
- const ptr_payload_cty = try dg.typeToIndex(ptr_payload_ty, .complete);
- if (ptr_cty != ptr_payload_cty) {
+ const payload_cty = try dg.typeToIndex(payload_ty, .forward);
+ if (ptr_child_cty != payload_cty) {
try writer.writeByte('(');
try dg.renderCType(writer, ptr_cty);
try writer.writeByte(')');
@@ -725,70 +752,90 @@ pub const DeclGen = struct {
try writer.writeAll(")->payload");
},
.elem => |elem| {
- const ptr_base_ty = Type.fromInterned(mod.intern_pool.typeOf(elem.base));
- const elem_ty = ptr_base_ty.elemType2(mod);
- const ptr_elem_ty = try mod.adjustPtrTypeChild(ptr_base_ty, elem_ty);
- const ptr_elem_cty = try dg.typeToIndex(ptr_elem_ty, .complete);
- if (ptr_cty != ptr_elem_cty) {
+ const ptr_base_ty = Type.fromInterned(ip.typeOf(elem.base));
+ const elem_ty = ptr_base_ty.elemType2(zcu);
+ const elem_cty = try dg.typeToIndex(elem_ty, .forward);
+ if (ptr_child_cty != elem_cty) {
try writer.writeByte('(');
try dg.renderCType(writer, ptr_cty);
try writer.writeByte(')');
}
try writer.writeAll("&(");
- if (mod.intern_pool.indexToKey(ptr_base_ty.toIntern()).ptr_type.flags.size == .One)
+ if (ip.indexToKey(ptr_base_ty.toIntern()).ptr_type.flags.size == .One)
try writer.writeByte('*');
try dg.renderParentPtr(writer, elem.base, location);
try writer.print(")[{d}]", .{elem.index});
},
.field => |field| {
- const ptr_base_ty = Type.fromInterned(mod.intern_pool.typeOf(field.base));
- const base_ty = ptr_base_ty.childType(mod);
+ const ptr_base_ty = Type.fromInterned(ip.typeOf(field.base));
+ const base_ty = ptr_base_ty.childType(zcu);
// Ensure complete type definition is visible before accessing fields.
_ = try dg.typeToIndex(base_ty, .complete);
- const field_ty = switch (mod.intern_pool.indexToKey(base_ty.toIntern())) {
- .anon_struct_type, .struct_type, .union_type => base_ty.structFieldType(@as(usize, @intCast(field.index)), mod),
- .ptr_type => |ptr_type| switch (ptr_type.flags.size) {
- .One, .Many, .C => unreachable,
- .Slice => switch (field.index) {
- Value.slice_ptr_index => base_ty.slicePtrFieldType(mod),
- Value.slice_len_index => Type.usize,
- else => unreachable,
- },
+ switch (fieldLocation(ptr_base_ty, ptr_ty, @as(u32, @intCast(field.index)), zcu)) {
+ .begin => {
+ const ptr_base_cty = try dg.typeToIndex(ptr_base_ty, .complete);
+ if (ptr_cty != ptr_base_cty) {
+ try writer.writeByte('(');
+ try dg.renderCType(writer, ptr_cty);
+ try writer.writeByte(')');
+ }
+ try dg.renderParentPtr(writer, field.base, location);
},
- else => unreachable,
- };
- const ptr_field_ty = try mod.adjustPtrTypeChild(ptr_base_ty, field_ty);
- const ptr_field_cty = try dg.typeToIndex(ptr_field_ty, .complete);
- if (ptr_cty != ptr_field_cty) {
- try writer.writeByte('(');
- try dg.renderCType(writer, ptr_cty);
- try writer.writeByte(')');
- }
- switch (fieldLocation(ptr_base_ty, ptr_ty, @as(u32, @intCast(field.index)), mod)) {
- .begin => try dg.renderParentPtr(writer, field.base, location),
.field => |name| {
+ const field_ty = switch (ip.indexToKey(base_ty.toIntern())) {
+ .anon_struct_type,
+ .struct_type,
+ .union_type,
+ => base_ty.structFieldType(@as(usize, @intCast(field.index)), zcu),
+ .ptr_type => |ptr_type| switch (ptr_type.flags.size) {
+ .One, .Many, .C => unreachable,
+ .Slice => switch (field.index) {
+ Value.slice_ptr_index => base_ty.slicePtrFieldType(zcu),
+ Value.slice_len_index => Type.usize,
+ else => unreachable,
+ },
+ },
+ else => unreachable,
+ };
+ const field_cty = try dg.typeToIndex(field_ty, .forward);
+ if (ptr_child_cty != field_cty) {
+ try writer.writeByte('(');
+ try dg.renderCType(writer, ptr_cty);
+ try writer.writeByte(')');
+ }
try writer.writeAll("&(");
try dg.renderParentPtr(writer, field.base, location);
try writer.writeAll(")->");
try dg.writeCValue(writer, name);
},
.byte_offset => |byte_offset| {
- const u8_ptr_ty = try mod.adjustPtrTypeChild(ptr_ty, Type.u8);
- const byte_offset_val = try mod.intValue(Type.usize, byte_offset);
+ const u8_ptr_ty = try zcu.adjustPtrTypeChild(ptr_ty, Type.u8);
+ const u8_ptr_cty = try dg.typeToIndex(u8_ptr_ty, .complete);
+ if (ptr_cty != u8_ptr_cty) {
+ try writer.writeByte('(');
+ try dg.renderCType(writer, ptr_cty);
+ try writer.writeByte(')');
+ }
try writer.writeAll("((");
- try dg.renderType(writer, u8_ptr_ty);
+ try dg.renderCType(writer, u8_ptr_cty);
try writer.writeByte(')');
try dg.renderParentPtr(writer, field.base, location);
try writer.print(" + {})", .{
- try dg.fmtIntLiteral(Type.usize, byte_offset_val, .Other),
+ try dg.fmtIntLiteral(try zcu.intValue(Type.usize, byte_offset), .Other),
});
},
.end => {
+ const ptr_base_cty = try dg.typeToIndex(ptr_base_ty, .complete);
+ if (ptr_cty != ptr_base_cty) {
+ try writer.writeByte('(');
+ try dg.renderCType(writer, ptr_cty);
+ try writer.writeByte(')');
+ }
try writer.writeAll("((");
try dg.renderParentPtr(writer, field.base, location);
try writer.print(") + {})", .{
- try dg.fmtIntLiteral(Type.usize, try mod.intValue(Type.usize, 1), .Other),
+ try dg.fmtIntLiteral(try zcu.intValue(Type.usize, 1), .Other),
});
},
}
@@ -800,215 +847,21 @@ pub const DeclGen = struct {
fn renderValue(
dg: *DeclGen,
writer: anytype,
- ty: Type,
val: Value,
location: ValueRenderLocation,
) error{ OutOfMemory, AnalysisFail }!void {
- const mod = dg.module;
- const ip = &mod.intern_pool;
+ const zcu = dg.zcu;
+ const ip = &zcu.intern_pool;
+ const target = &dg.mod.resolved_target.result;
- const target = mod.getTarget();
const initializer_type: ValueRenderLocation = switch (location) {
.StaticInitializer => .StaticInitializer,
else => .Initializer,
};
- const safety_on = switch (mod.optimizeMode()) {
- .Debug, .ReleaseSafe => true,
- .ReleaseFast, .ReleaseSmall => false,
- };
-
- if (val.isUndefDeep(mod)) {
- switch (ty.zigTypeTag(mod)) {
- .Bool => {
- if (safety_on) {
- return writer.writeAll("0xaa");
- } else {
- return writer.writeAll("false");
- }
- },
- .Int, .Enum, .ErrorSet => return writer.print("{x}", .{try dg.fmtIntLiteral(ty, val, location)}),
- .Float => {
- const bits = ty.floatBits(target);
- // All unsigned ints matching float types are pre-allocated.
- const repr_ty = mod.intType(.unsigned, bits) catch unreachable;
-
- try writer.writeAll("zig_make_");
- try dg.renderTypeForBuiltinFnName(writer, ty);
- try writer.writeByte('(');
- switch (bits) {
- 16 => try writer.print("{x}", .{@as(f16, @bitCast(undefPattern(i16)))}),
- 32 => try writer.print("{x}", .{@as(f32, @bitCast(undefPattern(i32)))}),
- 64 => try writer.print("{x}", .{@as(f64, @bitCast(undefPattern(i64)))}),
- 80 => try writer.print("{x}", .{@as(f80, @bitCast(undefPattern(i80)))}),
- 128 => try writer.print("{x}", .{@as(f128, @bitCast(undefPattern(i128)))}),
- else => unreachable,
- }
- try writer.writeAll(", ");
- try dg.renderValue(writer, repr_ty, Value.undef, .FunctionArgument);
- return writer.writeByte(')');
- },
- .Pointer => if (ty.isSlice(mod)) {
- if (!location.isInitializer()) {
- try writer.writeByte('(');
- try dg.renderType(writer, ty);
- try writer.writeByte(')');
- }
-
- try writer.writeAll("{(");
- const ptr_ty = ty.slicePtrFieldType(mod);
- try dg.renderType(writer, ptr_ty);
- return writer.print("){x}, {0x}}}", .{try dg.fmtIntLiteral(Type.usize, val, .Other)});
- } else {
- try writer.writeAll("((");
- try dg.renderType(writer, ty);
- return writer.print("){x})", .{try dg.fmtIntLiteral(Type.usize, val, .Other)});
- },
- .Optional => {
- const payload_ty = ty.optionalChild(mod);
-
- if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
- return dg.renderValue(writer, Type.bool, val, location);
- }
-
- if (ty.optionalReprIsPayload(mod)) {
- return dg.renderValue(writer, payload_ty, val, location);
- }
-
- if (!location.isInitializer()) {
- try writer.writeByte('(');
- try dg.renderType(writer, ty);
- try writer.writeByte(')');
- }
-
- try writer.writeAll("{ .payload = ");
- try dg.renderValue(writer, payload_ty, val, initializer_type);
- try writer.writeAll(", .is_null = ");
- try dg.renderValue(writer, Type.bool, val, initializer_type);
- return writer.writeAll(" }");
- },
- .Struct => switch (ty.containerLayout(mod)) {
- .auto, .@"extern" => {
- if (!location.isInitializer()) {
- try writer.writeByte('(');
- try dg.renderType(writer, ty);
- try writer.writeByte(')');
- }
-
- try writer.writeByte('{');
- var empty = true;
- for (0..ty.structFieldCount(mod)) |field_index| {
- if (ty.structFieldIsComptime(field_index, mod)) continue;
- const field_ty = ty.structFieldType(field_index, mod);
- if (!field_ty.hasRuntimeBits(mod)) continue;
-
- if (!empty) try writer.writeByte(',');
- try dg.renderValue(writer, field_ty, val, initializer_type);
-
- empty = false;
- }
-
- return writer.writeByte('}');
- },
- .@"packed" => return writer.print("{x}", .{try dg.fmtIntLiteral(ty, Value.undef, .Other)}),
- },
- .Union => {
- if (!location.isInitializer()) {
- try writer.writeByte('(');
- try dg.renderType(writer, ty);
- try writer.writeByte(')');
- }
-
- try writer.writeByte('{');
- if (ty.unionTagTypeSafety(mod)) |tag_ty| {
- const layout = ty.unionGetLayout(mod);
- if (layout.tag_size != 0) {
- try writer.writeAll(" .tag = ");
- try dg.renderValue(writer, tag_ty, val, initializer_type);
- }
- if (ty.unionHasAllZeroBitFieldTypes(mod)) return try writer.writeByte('}');
- if (layout.tag_size != 0) try writer.writeByte(',');
- try writer.writeAll(" .payload = {");
- }
- const union_obj = mod.typeToUnion(ty).?;
- for (0..union_obj.field_types.len) |field_index| {
- const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);
- if (!field_ty.hasRuntimeBits(mod)) continue;
- try dg.renderValue(writer, field_ty, val, initializer_type);
- break;
- }
- if (ty.unionTagTypeSafety(mod)) |_| try writer.writeByte('}');
- return writer.writeByte('}');
- },
- .ErrorUnion => {
- const payload_ty = ty.errorUnionPayload(mod);
- const error_ty = ty.errorUnionSet(mod);
-
- if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
- return dg.renderValue(writer, error_ty, val, location);
- }
-
- if (!location.isInitializer()) {
- try writer.writeByte('(');
- try dg.renderType(writer, ty);
- try writer.writeByte(')');
- }
-
- try writer.writeAll("{ .payload = ");
- try dg.renderValue(writer, payload_ty, val, initializer_type);
- try writer.writeAll(", .error = ");
- try dg.renderValue(writer, error_ty, val, initializer_type);
- return writer.writeAll(" }");
- },
- .Array, .Vector => {
- const ai = ty.arrayInfo(mod);
- if (ai.elem_type.eql(Type.u8, mod)) {
- const c_len = ty.arrayLenIncludingSentinel(mod);
- var literal = stringLiteral(writer, c_len);
- try literal.start();
- var index: u64 = 0;
- while (index < c_len) : (index += 1)
- try literal.writeChar(0xaa);
- return literal.end();
- } else {
- if (!location.isInitializer()) {
- try writer.writeByte('(');
- try dg.renderType(writer, ty);
- try writer.writeByte(')');
- }
-
- try writer.writeByte('{');
- const c_len = ty.arrayLenIncludingSentinel(mod);
- var index: u64 = 0;
- while (index < c_len) : (index += 1) {
- if (index > 0) try writer.writeAll(", ");
- try dg.renderValue(writer, ty.childType(mod), val, initializer_type);
- }
- return writer.writeByte('}');
- }
- },
- .ComptimeInt,
- .ComptimeFloat,
- .Type,
- .EnumLiteral,
- .Void,
- .NoReturn,
- .Undefined,
- .Null,
- .Opaque,
- => unreachable,
-
- .Fn,
- .Frame,
- .AnyFrame,
- => |tag| return dg.fail("TODO: C backend: implement value of type {s}", .{
- @tagName(tag),
- }),
- }
- unreachable;
- }
-
- switch (ip.indexToKey(val.ip_index)) {
+ const ty = val.typeOf(zcu);
+ if (val.isUndefDeep(zcu)) return dg.renderUndefValue(writer, ty, location);
+ switch (ip.indexToKey(val.toIntern())) {
// types, not values
.int_type,
.ptr_type,
@@ -1050,26 +903,28 @@ pub const DeclGen = struct {
.empty_enum_value,
=> unreachable, // non-runtime values
.int => |int| switch (int.storage) {
- .u64, .i64, .big_int => try writer.print("{}", .{try dg.fmtIntLiteral(ty, val, location)}),
+ .u64, .i64, .big_int => try writer.print("{}", .{try dg.fmtIntLiteral(val, location)}),
.lazy_align, .lazy_size => {
try writer.writeAll("((");
try dg.renderType(writer, ty);
- return writer.print("){x})", .{try dg.fmtIntLiteral(Type.usize, val, .Other)});
+ try writer.print("){x})", .{try dg.fmtIntLiteral(
+ try zcu.intValue(Type.usize, val.toUnsignedInt(zcu)),
+ .Other,
+ )});
},
},
.err => |err| try writer.print("zig_error_{}", .{
fmtIdent(ip.stringToSlice(err.name)),
}),
.error_union => |error_union| {
- const payload_ty = ty.errorUnionPayload(mod);
- const error_ty = ty.errorUnionSet(mod);
- const err_int_ty = try mod.errorIntType();
- if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
+ const payload_ty = ty.errorUnionPayload(zcu);
+ const error_ty = ty.errorUnionSet(zcu);
+ const err_int_ty = try zcu.errorIntType();
+ if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
switch (error_union.val) {
.err_name => |err_name| return dg.renderValue(
writer,
- error_ty,
- Value.fromInterned((try mod.intern(.{ .err = .{
+ Value.fromInterned((try zcu.intern(.{ .err = .{
.ty = error_ty.toIntern(),
.name = err_name,
} }))),
@@ -1077,8 +932,7 @@ pub const DeclGen = struct {
),
.payload => return dg.renderValue(
writer,
- err_int_ty,
- try mod.intValue(err_int_ty, 0),
+ try zcu.intValue(err_int_ty, 0),
location,
),
}
@@ -1093,9 +947,8 @@ pub const DeclGen = struct {
try writer.writeAll("{ .payload = ");
try dg.renderValue(
writer,
- payload_ty,
Value.fromInterned(switch (error_union.val) {
- .err_name => try mod.intern(.{ .undef = payload_ty.ip_index }),
+ .err_name => (try zcu.undefValue(payload_ty)).toIntern(),
.payload => |payload| payload,
}),
initializer_type,
@@ -1104,8 +957,7 @@ pub const DeclGen = struct {
switch (error_union.val) {
.err_name => |err_name| try dg.renderValue(
writer,
- error_ty,
- Value.fromInterned((try mod.intern(.{ .err = .{
+ Value.fromInterned((try zcu.intern(.{ .err = .{
.ty = error_ty.toIntern(),
.name = err_name,
} }))),
@@ -1113,24 +965,23 @@ pub const DeclGen = struct {
),
.payload => try dg.renderValue(
writer,
- err_int_ty,
- try mod.intValue(err_int_ty, 0),
+ try zcu.intValue(err_int_ty, 0),
location,
),
}
try writer.writeAll(" }");
},
- .enum_tag => {
- const enum_tag = ip.indexToKey(val.ip_index).enum_tag;
- const int_tag_ty = ip.typeOf(enum_tag.int);
- try dg.renderValue(writer, Type.fromInterned(int_tag_ty), Value.fromInterned(enum_tag.int), location);
- },
+ .enum_tag => |enum_tag| try dg.renderValue(
+ writer,
+ Value.fromInterned(enum_tag.int),
+ location,
+ ),
.float => {
- const bits = ty.floatBits(target);
- const f128_val = val.toFloat(f128, mod);
+ const bits = ty.floatBits(target.*);
+ const f128_val = val.toFloat(f128, zcu);
// All unsigned ints matching float types are pre-allocated.
- const repr_ty = mod.intType(.unsigned, bits) catch unreachable;
+ const repr_ty = zcu.intType(.unsigned, bits) catch unreachable;
assert(bits <= 128);
var repr_val_limbs: [BigInt.calcTwosCompLimbCount(128)]BigIntLimb = undefined;
@@ -1141,26 +992,24 @@ pub const DeclGen = struct {
};
switch (bits) {
- 16 => repr_val_big.set(@as(u16, @bitCast(val.toFloat(f16, mod)))),
- 32 => repr_val_big.set(@as(u32, @bitCast(val.toFloat(f32, mod)))),
- 64 => repr_val_big.set(@as(u64, @bitCast(val.toFloat(f64, mod)))),
- 80 => repr_val_big.set(@as(u80, @bitCast(val.toFloat(f80, mod)))),
+ 16 => repr_val_big.set(@as(u16, @bitCast(val.toFloat(f16, zcu)))),
+ 32 => repr_val_big.set(@as(u32, @bitCast(val.toFloat(f32, zcu)))),
+ 64 => repr_val_big.set(@as(u64, @bitCast(val.toFloat(f64, zcu)))),
+ 80 => repr_val_big.set(@as(u80, @bitCast(val.toFloat(f80, zcu)))),
128 => repr_val_big.set(@as(u128, @bitCast(f128_val))),
else => unreachable,
}
- const repr_val = try mod.intValue_big(repr_ty, repr_val_big.toConst());
-
var empty = true;
if (std.math.isFinite(f128_val)) {
try writer.writeAll("zig_make_");
try dg.renderTypeForBuiltinFnName(writer, ty);
try writer.writeByte('(');
switch (bits) {
- 16 => try writer.print("{x}", .{val.toFloat(f16, mod)}),
- 32 => try writer.print("{x}", .{val.toFloat(f32, mod)}),
- 64 => try writer.print("{x}", .{val.toFloat(f64, mod)}),
- 80 => try writer.print("{x}", .{val.toFloat(f80, mod)}),
+ 16 => try writer.print("{x}", .{val.toFloat(f16, zcu)}),
+ 32 => try writer.print("{x}", .{val.toFloat(f32, zcu)}),
+ 64 => try writer.print("{x}", .{val.toFloat(f64, zcu)}),
+ 80 => try writer.print("{x}", .{val.toFloat(f80, zcu)}),
128 => try writer.print("{x}", .{f128_val}),
else => unreachable,
}
@@ -1200,17 +1049,20 @@ pub const DeclGen = struct {
if (std.math.isNan(f128_val)) switch (bits) {
// We only actually need to pass the significand, but it will get
// properly masked anyway, so just pass the whole value.
- 16 => try writer.print("\"0x{x}\"", .{@as(u16, @bitCast(val.toFloat(f16, mod)))}),
- 32 => try writer.print("\"0x{x}\"", .{@as(u32, @bitCast(val.toFloat(f32, mod)))}),
- 64 => try writer.print("\"0x{x}\"", .{@as(u64, @bitCast(val.toFloat(f64, mod)))}),
- 80 => try writer.print("\"0x{x}\"", .{@as(u80, @bitCast(val.toFloat(f80, mod)))}),
+ 16 => try writer.print("\"0x{x}\"", .{@as(u16, @bitCast(val.toFloat(f16, zcu)))}),
+ 32 => try writer.print("\"0x{x}\"", .{@as(u32, @bitCast(val.toFloat(f32, zcu)))}),
+ 64 => try writer.print("\"0x{x}\"", .{@as(u64, @bitCast(val.toFloat(f64, zcu)))}),
+ 80 => try writer.print("\"0x{x}\"", .{@as(u80, @bitCast(val.toFloat(f80, zcu)))}),
128 => try writer.print("\"0x{x}\"", .{@as(u128, @bitCast(f128_val))}),
else => unreachable,
};
try writer.writeAll(", ");
empty = false;
}
- try writer.print("{x}", .{try dg.fmtIntLiteral(repr_ty, repr_val, location)});
+ try writer.print("{x}", .{try dg.fmtIntLiteral(
+ try zcu.intValue_big(repr_ty, repr_val_big.toConst()),
+ location,
+ )});
if (!empty) try writer.writeByte(')');
},
.slice => |slice| {
@@ -1220,42 +1072,39 @@ pub const DeclGen = struct {
try writer.writeByte(')');
}
try writer.writeByte('{');
- try dg.renderValue(writer, ty.slicePtrFieldType(mod), Value.fromInterned(slice.ptr), initializer_type);
+ try dg.renderValue(writer, Value.fromInterned(slice.ptr), initializer_type);
try writer.writeAll(", ");
- try dg.renderValue(writer, Type.usize, Value.fromInterned(slice.len), initializer_type);
+ try dg.renderValue(writer, Value.fromInterned(slice.len), initializer_type);
try writer.writeByte('}');
},
.ptr => |ptr| switch (ptr.addr) {
- .decl => |d| try dg.renderDeclValue(writer, ty, val, d, location),
- .anon_decl => |decl_val| try dg.renderAnonDeclValue(writer, ty, val, decl_val, location),
+ .decl => |d| try dg.renderDeclValue(writer, val, d, location),
+ .anon_decl => |decl_val| try dg.renderAnonDeclValue(writer, val, decl_val, location),
.int => |int| {
try writer.writeAll("((");
try dg.renderType(writer, ty);
- try writer.print("){x})", .{
- try dg.fmtIntLiteral(Type.usize, Value.fromInterned(int), location),
- });
+ try writer.print("){x})", .{try dg.fmtIntLiteral(Value.fromInterned(int), location)});
},
.eu_payload,
.opt_payload,
.elem,
.field,
- => try dg.renderParentPtr(writer, val.ip_index, location),
+ => try dg.renderParentPtr(writer, val.toIntern(), location),
.comptime_field, .comptime_alloc => unreachable,
},
.opt => |opt| {
- const payload_ty = ty.optionalChild(mod);
+ const payload_ty = ty.optionalChild(zcu);
const is_null_val = Value.makeBool(opt.val == .none);
- if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod))
- return dg.renderValue(writer, Type.bool, is_null_val, location);
+ if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu))
+ return dg.renderValue(writer, is_null_val, location);
- if (ty.optionalReprIsPayload(mod)) return dg.renderValue(
+ if (ty.optionalReprIsPayload(zcu)) return dg.renderValue(
writer,
- payload_ty,
switch (opt.val) {
- .none => switch (payload_ty.zigTypeTag(mod)) {
- .ErrorSet => try mod.intValue(try mod.errorIntType(), 0),
- .Pointer => try mod.getCoerced(val, payload_ty),
+ .none => switch (payload_ty.zigTypeTag(zcu)) {
+ .ErrorSet => try zcu.intValue(try zcu.errorIntType(), 0),
+ .Pointer => try zcu.getCoerced(val, payload_ty),
else => unreachable,
},
else => |payload| Value.fromInterned(payload),
@@ -1270,15 +1119,19 @@ pub const DeclGen = struct {
}
try writer.writeAll("{ .payload = ");
- try dg.renderValue(writer, payload_ty, Value.fromInterned(switch (opt.val) {
- .none => try mod.intern(.{ .undef = payload_ty.ip_index }),
- else => |payload| payload,
- }), initializer_type);
+ switch (opt.val) {
+ .none => try dg.renderUndefValue(writer, payload_ty, initializer_type),
+ else => |payload| try dg.renderValue(
+ writer,
+ Value.fromInterned(payload),
+ initializer_type,
+ ),
+ }
try writer.writeAll(", .is_null = ");
- try dg.renderValue(writer, Type.bool, is_null_val, initializer_type);
+ try dg.renderValue(writer, is_null_val, initializer_type);
try writer.writeAll(" }");
},
- .aggregate => switch (ip.indexToKey(ty.ip_index)) {
+ .aggregate => switch (ip.indexToKey(ty.toIntern())) {
.array_type, .vector_type => {
if (location == .FunctionArgument) {
try writer.writeByte('(');
@@ -1287,21 +1140,21 @@ pub const DeclGen = struct {
}
// Fall back to generic implementation.
- const ai = ty.arrayInfo(mod);
- if (ai.elem_type.eql(Type.u8, mod)) {
- var literal = stringLiteral(writer, ty.arrayLenIncludingSentinel(mod));
+ const ai = ty.arrayInfo(zcu);
+ if (ai.elem_type.eql(Type.u8, zcu)) {
+ var literal = stringLiteral(writer, ty.arrayLenIncludingSentinel(zcu));
try literal.start();
var index: usize = 0;
while (index < ai.len) : (index += 1) {
- const elem_val = try val.elemValue(mod, index);
- const elem_val_u8: u8 = if (elem_val.isUndef(mod))
+ const elem_val = try val.elemValue(zcu, index);
+ const elem_val_u8: u8 = if (elem_val.isUndef(zcu))
undefPattern(u8)
else
- @intCast(elem_val.toUnsignedInt(mod));
+ @intCast(elem_val.toUnsignedInt(zcu));
try literal.writeChar(elem_val_u8);
}
if (ai.sentinel) |s| {
- const s_u8: u8 = @intCast(s.toUnsignedInt(mod));
+ const s_u8: u8 = @intCast(s.toUnsignedInt(zcu));
if (s_u8 != 0) try literal.writeChar(s_u8);
}
try literal.end();
@@ -1310,12 +1163,12 @@ pub const DeclGen = struct {
var index: usize = 0;
while (index < ai.len) : (index += 1) {
if (index != 0) try writer.writeByte(',');
- const elem_val = try val.elemValue(mod, index);
- try dg.renderValue(writer, ai.elem_type, elem_val, initializer_type);
+ const elem_val = try val.elemValue(zcu, index);
+ try dg.renderValue(writer, elem_val, initializer_type);
}
if (ai.sentinel) |s| {
if (index != 0) try writer.writeByte(',');
- try dg.renderValue(writer, ai.elem_type, s, initializer_type);
+ try dg.renderValue(writer, s, initializer_type);
}
try writer.writeByte('}');
}
@@ -1333,19 +1186,21 @@ pub const DeclGen = struct {
const comptime_val = tuple.values.get(ip)[field_index];
if (comptime_val != .none) continue;
const field_ty = Type.fromInterned(tuple.types.get(ip)[field_index]);
- if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
+ if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
if (!empty) try writer.writeByte(',');
- const field_val = Value.fromInterned(switch (ip.indexToKey(val.ip_index).aggregate.storage) {
- .bytes => |bytes| try ip.get(mod.gpa, .{ .int = .{
- .ty = field_ty.toIntern(),
- .storage = .{ .u64 = bytes[field_index] },
- } }),
- .elems => |elems| elems[field_index],
- .repeated_elem => |elem| elem,
- });
- try dg.renderValue(writer, field_ty, field_val, initializer_type);
+ const field_val = Value.fromInterned(
+ switch (ip.indexToKey(val.toIntern()).aggregate.storage) {
+ .bytes => |bytes| try ip.get(zcu.gpa, .{ .int = .{
+ .ty = field_ty.toIntern(),
+ .storage = .{ .u64 = bytes[field_index] },
+ } }),
+ .elems => |elems| elems[field_index],
+ .repeated_elem => |elem| elem,
+ },
+ );
+ try dg.renderValue(writer, field_val, initializer_type);
empty = false;
}
@@ -1366,43 +1221,43 @@ pub const DeclGen = struct {
for (0..struct_type.field_types.len) |field_index| {
const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);
if (struct_type.fieldIsComptime(ip, field_index)) continue;
- if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
+ if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
if (!empty) try writer.writeByte(',');
- const field_val = switch (ip.indexToKey(val.ip_index).aggregate.storage) {
- .bytes => |bytes| try ip.get(mod.gpa, .{ .int = .{
+ const field_val = switch (ip.indexToKey(val.toIntern()).aggregate.storage) {
+ .bytes => |bytes| try ip.get(zcu.gpa, .{ .int = .{
.ty = field_ty.toIntern(),
.storage = .{ .u64 = bytes[field_index] },
} }),
.elems => |elems| elems[field_index],
.repeated_elem => |elem| elem,
};
- try dg.renderValue(writer, field_ty, Value.fromInterned(field_val), initializer_type);
+ try dg.renderValue(writer, Value.fromInterned(field_val), initializer_type);
empty = false;
}
try writer.writeByte('}');
},
.@"packed" => {
- const int_info = ty.intInfo(mod);
+ const int_info = ty.intInfo(zcu);
const bits = Type.smallestUnsignedBits(int_info.bits - 1);
- const bit_offset_ty = try mod.intType(.unsigned, bits);
+ const bit_offset_ty = try zcu.intType(.unsigned, bits);
var bit_offset: u64 = 0;
var eff_num_fields: usize = 0;
for (0..struct_type.field_types.len) |field_index| {
const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);
- if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
+ if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
eff_num_fields += 1;
}
if (eff_num_fields == 0) {
try writer.writeByte('(');
- try dg.renderValue(writer, ty, Value.undef, initializer_type);
+ try dg.renderUndefValue(writer, ty, initializer_type);
try writer.writeByte(')');
- } else if (ty.bitSize(mod) > 64) {
+ } else if (ty.bitSize(zcu) > 64) {
// zig_or_u128(zig_or_u128(zig_shl_u128(a, a_off), zig_shl_u128(b, b_off)), zig_shl_u128(c, c_off))
var num_or = eff_num_fields - 1;
while (num_or > 0) : (num_or -= 1) {
@@ -1415,10 +1270,10 @@ pub const DeclGen = struct {
var needs_closing_paren = false;
for (0..struct_type.field_types.len) |field_index| {
const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);
- if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
+ if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
- const field_val = switch (ip.indexToKey(val.ip_index).aggregate.storage) {
- .bytes => |bytes| try ip.get(mod.gpa, .{ .int = .{
+ const field_val = switch (ip.indexToKey(val.toIntern()).aggregate.storage) {
+ .bytes => |bytes| try ip.get(zcu.gpa, .{ .int = .{
.ty = field_ty.toIntern(),
.storage = .{ .u64 = bytes[field_index] },
} }),
@@ -1432,8 +1287,7 @@ pub const DeclGen = struct {
try writer.writeByte('(');
try dg.renderIntCast(writer, ty, cast_context, field_ty, .FunctionArgument);
try writer.writeAll(", ");
- const bit_offset_val = try mod.intValue(bit_offset_ty, bit_offset);
- try dg.renderValue(writer, bit_offset_ty, bit_offset_val, .FunctionArgument);
+ try dg.renderValue(writer, try zcu.intValue(bit_offset_ty, bit_offset), .FunctionArgument);
try writer.writeByte(')');
} else {
try dg.renderIntCast(writer, ty, cast_context, field_ty, .FunctionArgument);
@@ -1442,7 +1296,7 @@ pub const DeclGen = struct {
if (needs_closing_paren) try writer.writeByte(')');
if (eff_index != eff_num_fields - 1) try writer.writeAll(", ");
- bit_offset += field_ty.bitSize(mod);
+ bit_offset += field_ty.bitSize(zcu);
needs_closing_paren = true;
eff_index += 1;
}
@@ -1452,15 +1306,15 @@ pub const DeclGen = struct {
var empty = true;
for (0..struct_type.field_types.len) |field_index| {
const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);
- if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
+ if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
if (!empty) try writer.writeAll(" | ");
try writer.writeByte('(');
try dg.renderType(writer, ty);
try writer.writeByte(')');
- const field_val = switch (ip.indexToKey(val.ip_index).aggregate.storage) {
- .bytes => |bytes| try ip.get(mod.gpa, .{ .int = .{
+ const field_val = switch (ip.indexToKey(val.toIntern()).aggregate.storage) {
+ .bytes => |bytes| try ip.get(zcu.gpa, .{ .int = .{
.ty = field_ty.toIntern(),
.storage = .{ .u64 = bytes[field_index] },
} }),
@@ -1469,15 +1323,14 @@ pub const DeclGen = struct {
};
if (bit_offset != 0) {
- try dg.renderValue(writer, field_ty, Value.fromInterned(field_val), .Other);
+ try dg.renderValue(writer, Value.fromInterned(field_val), .Other);
try writer.writeAll(" << ");
- const bit_offset_val = try mod.intValue(bit_offset_ty, bit_offset);
- try dg.renderValue(writer, bit_offset_ty, bit_offset_val, .FunctionArgument);
+ try dg.renderValue(writer, try zcu.intValue(bit_offset_ty, bit_offset), .FunctionArgument);
} else {
- try dg.renderValue(writer, field_ty, Value.fromInterned(field_val), .Other);
+ try dg.renderValue(writer, Value.fromInterned(field_val), .Other);
}
- bit_offset += field_ty.bitSize(mod);
+ bit_offset += field_ty.bitSize(zcu);
empty = false;
}
try writer.writeByte(')');
@@ -1488,9 +1341,9 @@ pub const DeclGen = struct {
else => unreachable,
},
.un => |un| {
- const union_obj = mod.typeToUnion(ty).?;
+ const union_obj = zcu.typeToUnion(ty).?;
if (un.tag == .none) {
- const backing_ty = try ty.unionBackingType(mod);
+ const backing_ty = try ty.unionBackingType(zcu);
switch (union_obj.getLayout(ip)) {
.@"packed" => {
if (!location.isInitializer()) {
@@ -1498,20 +1351,20 @@ pub const DeclGen = struct {
try dg.renderType(writer, backing_ty);
try writer.writeByte(')');
}
- try dg.renderValue(writer, backing_ty, Value.fromInterned(un.val), initializer_type);
+ try dg.renderValue(writer, Value.fromInterned(un.val), initializer_type);
},
.@"extern" => {
if (location == .StaticInitializer) {
return dg.fail("TODO: C backend: implement extern union backing type rendering in static initializers", .{});
}
- const ptr_ty = try mod.singleConstPtrType(ty);
+ const ptr_ty = try zcu.singleConstPtrType(ty);
try writer.writeAll("*((");
try dg.renderType(writer, ptr_ty);
try writer.writeAll(")(");
try dg.renderType(writer, backing_ty);
try writer.writeAll("){");
- try dg.renderValue(writer, backing_ty, Value.fromInterned(un.val), initializer_type);
+ try dg.renderValue(writer, Value.fromInterned(un.val), initializer_type);
try writer.writeAll("})");
},
else => unreachable,
@@ -1523,21 +1376,21 @@ pub const DeclGen = struct {
try writer.writeByte(')');
}
- const field_index = mod.unionTagFieldIndex(union_obj, Value.fromInterned(un.tag)).?;
+ const field_index = zcu.unionTagFieldIndex(union_obj, Value.fromInterned(un.tag)).?;
const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);
const field_name = union_obj.loadTagType(ip).names.get(ip)[field_index];
if (union_obj.getLayout(ip) == .@"packed") {
- if (field_ty.hasRuntimeBits(mod)) {
- if (field_ty.isPtrAtRuntime(mod)) {
+ if (field_ty.hasRuntimeBits(zcu)) {
+ if (field_ty.isPtrAtRuntime(zcu)) {
try writer.writeByte('(');
try dg.renderType(writer, ty);
try writer.writeByte(')');
- } else if (field_ty.zigTypeTag(mod) == .Float) {
+ } else if (field_ty.zigTypeTag(zcu) == .Float) {
try writer.writeByte('(');
try dg.renderType(writer, ty);
try writer.writeByte(')');
}
- try dg.renderValue(writer, field_ty, Value.fromInterned(un.val), initializer_type);
+ try dg.renderValue(writer, Value.fromInterned(un.val), initializer_type);
} else {
try writer.writeAll("0");
}
@@ -1545,30 +1398,236 @@ pub const DeclGen = struct {
}
try writer.writeByte('{');
- if (ty.unionTagTypeSafety(mod)) |tag_ty| {
- const layout = mod.getUnionLayout(union_obj);
+ if (ty.unionTagTypeSafety(zcu)) |_| {
+ const layout = zcu.getUnionLayout(union_obj);
if (layout.tag_size != 0) {
try writer.writeAll(" .tag = ");
- try dg.renderValue(writer, tag_ty, Value.fromInterned(un.tag), initializer_type);
+ try dg.renderValue(writer, Value.fromInterned(un.tag), initializer_type);
}
- if (ty.unionHasAllZeroBitFieldTypes(mod)) return try writer.writeByte('}');
+ if (ty.unionHasAllZeroBitFieldTypes(zcu)) return try writer.writeByte('}');
if (layout.tag_size != 0) try writer.writeByte(',');
try writer.writeAll(" .payload = {");
}
- if (field_ty.hasRuntimeBits(mod)) {
+ if (field_ty.hasRuntimeBits(zcu)) {
try writer.print(" .{ } = ", .{fmtIdent(ip.stringToSlice(field_name))});
- try dg.renderValue(writer, field_ty, Value.fromInterned(un.val), initializer_type);
+ try dg.renderValue(writer, Value.fromInterned(un.val), initializer_type);
try writer.writeByte(' ');
} else for (0..union_obj.field_types.len) |this_field_index| {
const this_field_ty = Type.fromInterned(union_obj.field_types.get(ip)[this_field_index]);
- if (!this_field_ty.hasRuntimeBits(mod)) continue;
- try dg.renderValue(writer, this_field_ty, Value.undef, initializer_type);
+ if (!this_field_ty.hasRuntimeBits(zcu)) continue;
+ try dg.renderUndefValue(writer, this_field_ty, initializer_type);
break;
}
- if (ty.unionTagTypeSafety(mod)) |_| try writer.writeByte('}');
+ if (ty.unionTagTypeSafety(zcu)) |_| try writer.writeByte('}');
+ try writer.writeByte('}');
+ }
+ },
+ }
+ }
+
+ fn renderUndefValue(
+ dg: *DeclGen,
+ writer: anytype,
+ ty: Type,
+ location: ValueRenderLocation,
+ ) error{ OutOfMemory, AnalysisFail }!void {
+ const zcu = dg.zcu;
+ const ip = &zcu.intern_pool;
+ const target = &dg.mod.resolved_target.result;
+
+ const initializer_type: ValueRenderLocation = switch (location) {
+ .StaticInitializer => .StaticInitializer,
+ else => .Initializer,
+ };
+
+ const safety_on = switch (zcu.optimizeMode()) {
+ .Debug, .ReleaseSafe => true,
+ .ReleaseFast, .ReleaseSmall => false,
+ };
+
+ switch (ty.zigTypeTag(zcu)) {
+ .Bool => try writer.writeAll(if (safety_on) "0xaa" else "false"),
+ .Int, .Enum, .ErrorSet => try writer.print("{x}", .{
+ try dg.fmtIntLiteral(try zcu.undefValue(ty), location),
+ }),
+ .Float => {
+ const bits = ty.floatBits(target.*);
+ // All unsigned ints matching float types are pre-allocated.
+ const repr_ty = zcu.intType(.unsigned, bits) catch unreachable;
+
+ try writer.writeAll("zig_make_");
+ try dg.renderTypeForBuiltinFnName(writer, ty);
+ try writer.writeByte('(');
+ switch (bits) {
+ 16 => try writer.print("{x}", .{@as(f16, @bitCast(undefPattern(i16)))}),
+ 32 => try writer.print("{x}", .{@as(f32, @bitCast(undefPattern(i32)))}),
+ 64 => try writer.print("{x}", .{@as(f64, @bitCast(undefPattern(i64)))}),
+ 80 => try writer.print("{x}", .{@as(f80, @bitCast(undefPattern(i80)))}),
+ 128 => try writer.print("{x}", .{@as(f128, @bitCast(undefPattern(i128)))}),
+ else => unreachable,
+ }
+ try writer.writeAll(", ");
+ try dg.renderUndefValue(writer, repr_ty, .FunctionArgument);
+ try writer.writeByte(')');
+ },
+ .Pointer => if (ty.isSlice(zcu)) {
+ if (!location.isInitializer()) {
+ try writer.writeByte('(');
+ try dg.renderType(writer, ty);
+ try writer.writeByte(')');
+ }
+
+ try writer.writeAll("{(");
+ const ptr_ty = ty.slicePtrFieldType(zcu);
+ try dg.renderType(writer, ptr_ty);
+ try writer.print("){x}, {0x}}}", .{try dg.fmtIntLiteral(try zcu.undefValue(Type.usize), .Other)});
+ } else {
+ try writer.writeAll("((");
+ try dg.renderType(writer, ty);
+ try writer.print("){x})", .{try dg.fmtIntLiteral(try zcu.undefValue(Type.usize), .Other)});
+ },
+ .Optional => {
+ const payload_ty = ty.optionalChild(zcu);
+
+ if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
+ return dg.renderUndefValue(writer, Type.bool, location);
+ }
+
+ if (ty.optionalReprIsPayload(zcu)) {
+ return dg.renderUndefValue(writer, payload_ty, location);
+ }
+
+ if (!location.isInitializer()) {
+ try writer.writeByte('(');
+ try dg.renderType(writer, ty);
+ try writer.writeByte(')');
+ }
+
+ try writer.writeAll("{ .payload = ");
+ try dg.renderUndefValue(writer, payload_ty, initializer_type);
+ try writer.writeAll(", .is_null = ");
+ try dg.renderUndefValue(writer, Type.bool, initializer_type);
+ try writer.writeAll(" }");
+ },
+ .Struct => switch (ty.containerLayout(zcu)) {
+ .auto, .@"extern" => {
+ if (!location.isInitializer()) {
+ try writer.writeByte('(');
+ try dg.renderType(writer, ty);
+ try writer.writeByte(')');
+ }
+
+ try writer.writeByte('{');
+ var empty = true;
+ for (0..ty.structFieldCount(zcu)) |field_index| {
+ if (ty.structFieldIsComptime(field_index, zcu)) continue;
+ const field_ty = ty.structFieldType(field_index, zcu);
+ if (!field_ty.hasRuntimeBits(zcu)) continue;
+
+ if (!empty) try writer.writeByte(',');
+ try dg.renderUndefValue(writer, field_ty, initializer_type);
+
+ empty = false;
+ }
+
try writer.writeByte('}');
+ },
+ .@"packed" => try writer.print("{x}", .{
+ try dg.fmtIntLiteral(try zcu.undefValue(ty), .Other),
+ }),
+ },
+ .Union => {
+ if (!location.isInitializer()) {
+ try writer.writeByte('(');
+ try dg.renderType(writer, ty);
+ try writer.writeByte(')');
}
+
+ try writer.writeByte('{');
+ if (ty.unionTagTypeSafety(zcu)) |tag_ty| {
+ const layout = ty.unionGetLayout(zcu);
+ if (layout.tag_size != 0) {
+ try writer.writeAll(" .tag = ");
+ try dg.renderUndefValue(writer, tag_ty, initializer_type);
+ }
+ if (ty.unionHasAllZeroBitFieldTypes(zcu)) return try writer.writeByte('}');
+ if (layout.tag_size != 0) try writer.writeByte(',');
+ try writer.writeAll(" .payload = {");
+ }
+ const union_obj = zcu.typeToUnion(ty).?;
+ for (0..union_obj.field_types.len) |field_index| {
+ const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);
+ if (!field_ty.hasRuntimeBits(zcu)) continue;
+ try dg.renderUndefValue(writer, field_ty, initializer_type);
+ break;
+ }
+ if (ty.unionTagTypeSafety(zcu)) |_| try writer.writeByte('}');
+ try writer.writeByte('}');
},
+ .ErrorUnion => {
+ const payload_ty = ty.errorUnionPayload(zcu);
+ const error_ty = ty.errorUnionSet(zcu);
+
+ if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
+ return dg.renderUndefValue(writer, error_ty, location);
+ }
+
+ if (!location.isInitializer()) {
+ try writer.writeByte('(');
+ try dg.renderType(writer, ty);
+ try writer.writeByte(')');
+ }
+
+ try writer.writeAll("{ .payload = ");
+ try dg.renderUndefValue(writer, payload_ty, initializer_type);
+ try writer.writeAll(", .error = ");
+ try dg.renderUndefValue(writer, error_ty, initializer_type);
+ try writer.writeAll(" }");
+ },
+ .Array, .Vector => {
+ const ai = ty.arrayInfo(zcu);
+ if (ai.elem_type.eql(Type.u8, zcu)) {
+ const c_len = ty.arrayLenIncludingSentinel(zcu);
+ var literal = stringLiteral(writer, c_len);
+ try literal.start();
+ var index: u64 = 0;
+ while (index < c_len) : (index += 1)
+ try literal.writeChar(0xaa);
+ try literal.end();
+ } else {
+ if (!location.isInitializer()) {
+ try writer.writeByte('(');
+ try dg.renderType(writer, ty);
+ try writer.writeByte(')');
+ }
+
+ try writer.writeByte('{');
+ const c_len = ty.arrayLenIncludingSentinel(zcu);
+ var index: u64 = 0;
+ while (index < c_len) : (index += 1) {
+ if (index > 0) try writer.writeAll(", ");
+ try dg.renderUndefValue(writer, ty.childType(zcu), initializer_type);
+ }
+ try writer.writeByte('}');
+ }
+ },
+ .ComptimeInt,
+ .ComptimeFloat,
+ .Type,
+ .EnumLiteral,
+ .Void,
+ .NoReturn,
+ .Undefined,
+ .Null,
+ .Opaque,
+ => unreachable,
+
+ .Fn,
+ .Frame,
+ .AnyFrame,
+ => |tag| return dg.fail("TODO: C backend: implement value of type {s}", .{
+ @tagName(tag),
+ }),
}
}
@@ -1583,14 +1642,14 @@ pub const DeclGen = struct {
},
) !void {
const store = &dg.ctypes.set;
- const mod = dg.module;
- const ip = &mod.intern_pool;
+ const zcu = dg.zcu;
+ const ip = &zcu.intern_pool;
- const fn_decl = mod.declPtr(fn_decl_index);
- const fn_ty = fn_decl.typeOf(mod);
+ const fn_decl = zcu.declPtr(fn_decl_index);
+ const fn_ty = fn_decl.typeOf(zcu);
const fn_cty_idx = try dg.typeToIndex(fn_ty, kind);
- const fn_info = mod.typeToFunc(fn_ty).?;
+ const fn_info = zcu.typeToFunc(fn_ty).?;
if (fn_info.cc == .Naked) {
switch (kind) {
.forward => try w.writeAll("zig_naked_decl "),
@@ -1598,11 +1657,11 @@ pub const DeclGen = struct {
else => unreachable,
}
}
- if (fn_decl.val.getFunction(mod)) |func| if (func.analysis(ip).is_cold)
+ if (fn_decl.val.getFunction(zcu)) |func| if (func.analysis(ip).is_cold)
try w.writeAll("zig_cold ");
if (fn_info.return_type == .noreturn_type) try w.writeAll("zig_noreturn ");
- var trailing = try renderTypePrefix(dg.pass, store.*, mod, w, fn_cty_idx, .suffix, .{});
+ var trailing = try renderTypePrefix(dg.pass, store.*, zcu, w, fn_cty_idx, .suffix, .{});
if (toCallingConvention(fn_info.cc)) |call_conv| {
try w.print("{}zig_callconv({s})", .{ trailing, call_conv });
@@ -1629,7 +1688,7 @@ pub const DeclGen = struct {
try renderTypeSuffix(
dg.pass,
store.*,
- mod,
+ zcu,
w,
fn_cty_idx,
.suffix,
@@ -1647,11 +1706,11 @@ pub const DeclGen = struct {
}
switch (name) {
.export_index => |export_index| mangled: {
- const maybe_exports = mod.decl_exports.get(fn_decl_index);
+ const maybe_exports = zcu.decl_exports.get(fn_decl_index);
const external_name = ip.stringToSlice(
if (maybe_exports) |exports|
exports.items[export_index].opts.name
- else if (fn_decl.isExtern(mod))
+ else if (fn_decl.isExtern(zcu))
fn_decl.name
else
break :mangled,
@@ -1694,15 +1753,15 @@ pub const DeclGen = struct {
}
fn typeToIndex(dg: *DeclGen, ty: Type, kind: CType.Kind) !CType.Index {
- return dg.ctypes.typeToIndex(dg.gpa, ty, dg.module, kind);
+ return dg.ctypes.typeToIndex(dg.gpa, ty, dg.zcu, dg.mod, kind);
}
fn typeToCType(dg: *DeclGen, ty: Type, kind: CType.Kind) !CType {
- return dg.ctypes.typeToCType(dg.gpa, ty, dg.module, kind);
+ return dg.ctypes.typeToCType(dg.gpa, ty, dg.zcu, dg.mod, kind);
}
fn byteSize(dg: *DeclGen, cty: CType) u64 {
- return cty.byteSize(dg.ctypes.set, dg.module.getTarget());
+ return cty.byteSize(dg.ctypes.set, dg.mod);
}
/// Renders a type as a single identifier, generating intermediate typedefs
@@ -1722,9 +1781,9 @@ pub const DeclGen = struct {
fn renderCType(dg: *DeclGen, w: anytype, idx: CType.Index) error{ OutOfMemory, AnalysisFail }!void {
const store = &dg.ctypes.set;
- const mod = dg.module;
- _ = try renderTypePrefix(dg.pass, store.*, mod, w, idx, .suffix, .{});
- try renderTypeSuffix(dg.pass, store.*, mod, w, idx, .suffix, .{});
+ const zcu = dg.zcu;
+ _ = try renderTypePrefix(dg.pass, store.*, zcu, w, idx, .suffix, .{});
+ try renderTypeSuffix(dg.pass, store.*, zcu, w, idx, .suffix, .{});
}
const IntCastContext = union(enum) {
@@ -1737,15 +1796,13 @@ pub const DeclGen = struct {
value: Value,
},
- pub fn writeValue(self: *const IntCastContext, dg: *DeclGen, w: anytype, value_ty: Type, location: ValueRenderLocation) !void {
+ pub fn writeValue(self: *const IntCastContext, dg: *DeclGen, w: anytype, location: ValueRenderLocation) !void {
switch (self.*) {
.c_value => |v| {
try v.f.writeCValue(w, v.value, location);
try v.v.elem(v.f, w);
},
- .value => |v| {
- try dg.renderValue(w, value_ty, v.value, location);
- },
+ .value => |v| try dg.renderValue(w, v.value, location),
}
}
};
@@ -1764,18 +1821,18 @@ pub const DeclGen = struct {
/// | > 64 bit integer | < 64 bit integer | zig_make_<dest_ty>(0, src)
/// | > 64 bit integer | > 64 bit integer | zig_make_<dest_ty>(zig_hi_<src_ty>(src), zig_lo_<src_ty>(src))
fn renderIntCast(dg: *DeclGen, w: anytype, dest_ty: Type, context: IntCastContext, src_ty: Type, location: ValueRenderLocation) !void {
- const mod = dg.module;
- const dest_bits = dest_ty.bitSize(mod);
- const dest_int_info = dest_ty.intInfo(mod);
+ const zcu = dg.zcu;
+ const dest_bits = dest_ty.bitSize(zcu);
+ const dest_int_info = dest_ty.intInfo(zcu);
- const src_is_ptr = src_ty.isPtrAtRuntime(mod);
+ const src_is_ptr = src_ty.isPtrAtRuntime(zcu);
const src_eff_ty: Type = if (src_is_ptr) switch (dest_int_info.signedness) {
.unsigned => Type.usize,
.signed => Type.isize,
} else src_ty;
- const src_bits = src_eff_ty.bitSize(mod);
- const src_int_info = if (src_eff_ty.isAbiInt(mod)) src_eff_ty.intInfo(mod) else null;
+ const src_bits = src_eff_ty.bitSize(zcu);
+ const src_int_info = if (src_eff_ty.isAbiInt(zcu)) src_eff_ty.intInfo(zcu) else null;
if (dest_bits <= 64 and src_bits <= 64) {
const needs_cast = src_int_info == null or
(toCIntBits(dest_int_info.bits) != toCIntBits(src_int_info.?.bits) or
@@ -1791,7 +1848,7 @@ pub const DeclGen = struct {
try dg.renderType(w, src_eff_ty);
try w.writeByte(')');
}
- try context.writeValue(dg, w, src_ty, location);
+ try context.writeValue(dg, w, location);
} else if (dest_bits <= 64 and src_bits > 64) {
assert(!src_is_ptr);
if (dest_bits < 64) {
@@ -1802,7 +1859,7 @@ pub const DeclGen = struct {
try w.writeAll("zig_lo_");
try dg.renderTypeForBuiltinFnName(w, src_eff_ty);
try w.writeByte('(');
- try context.writeValue(dg, w, src_ty, .FunctionArgument);
+ try context.writeValue(dg, w, .FunctionArgument);
try w.writeByte(')');
} else if (dest_bits > 64 and src_bits <= 64) {
try w.writeAll("zig_make_");
@@ -1813,7 +1870,7 @@ pub const DeclGen = struct {
try dg.renderType(w, src_eff_ty);
try w.writeByte(')');
}
- try context.writeValue(dg, w, src_ty, .FunctionArgument);
+ try context.writeValue(dg, w, .FunctionArgument);
try w.writeByte(')');
} else {
assert(!src_is_ptr);
@@ -1822,11 +1879,11 @@ pub const DeclGen = struct {
try w.writeAll("(zig_hi_");
try dg.renderTypeForBuiltinFnName(w, src_eff_ty);
try w.writeByte('(');
- try context.writeValue(dg, w, src_ty, .FunctionArgument);
+ try context.writeValue(dg, w, .FunctionArgument);
try w.writeAll("), zig_lo_");
try dg.renderTypeForBuiltinFnName(w, src_eff_ty);
try w.writeByte('(');
- try context.writeValue(dg, w, src_ty, .FunctionArgument);
+ try context.writeValue(dg, w, .FunctionArgument);
try w.writeAll("))");
}
}
@@ -1848,8 +1905,8 @@ pub const DeclGen = struct {
alignment: Alignment,
kind: CType.Kind,
) error{ OutOfMemory, AnalysisFail }!void {
- const mod = dg.module;
- const alignas = CType.AlignAs.init(alignment, ty.abiAlignment(mod));
+ const zcu = dg.zcu;
+ const alignas = CType.AlignAs.init(alignment, ty.abiAlignment(zcu));
try dg.renderCTypeAndName(w, try dg.typeToIndex(ty, kind), name, qualifiers, alignas);
}
@@ -1862,7 +1919,7 @@ pub const DeclGen = struct {
alignas: CType.AlignAs,
) error{ OutOfMemory, AnalysisFail }!void {
const store = &dg.ctypes.set;
- const mod = dg.module;
+ const zcu = dg.zcu;
switch (alignas.abiOrder()) {
.lt => try w.print("zig_under_align({}) ", .{alignas.toByteUnits()}),
@@ -1870,39 +1927,46 @@ pub const DeclGen = struct {
.gt => try w.print("zig_align({}) ", .{alignas.toByteUnits()}),
}
- const trailing = try renderTypePrefix(dg.pass, store.*, mod, w, cty_idx, .suffix, qualifiers);
+ const trailing = try renderTypePrefix(dg.pass, store.*, zcu, w, cty_idx, .suffix, qualifiers);
try w.print("{}", .{trailing});
- try dg.writeCValue(w, name);
- try renderTypeSuffix(dg.pass, store.*, mod, w, cty_idx, .suffix, .{});
+ try dg.writeName(w, name);
+ try renderTypeSuffix(dg.pass, store.*, zcu, w, cty_idx, .suffix, .{});
}
fn declIsGlobal(dg: *DeclGen, val: Value) bool {
- const mod = dg.module;
- return switch (mod.intern_pool.indexToKey(val.ip_index)) {
- .variable => |variable| mod.decl_exports.contains(variable.decl),
+ const zcu = dg.zcu;
+ return switch (zcu.intern_pool.indexToKey(val.toIntern())) {
+ .variable => |variable| zcu.decl_exports.contains(variable.decl),
.extern_func => true,
- .func => |func| mod.decl_exports.contains(func.owner_decl),
+ .func => |func| zcu.decl_exports.contains(func.owner_decl),
else => unreachable,
};
}
+ fn writeName(dg: *DeclGen, w: anytype, c_value: CValue) !void {
+ switch (c_value) {
+ .new_local, .local => |i| try w.print("t{d}", .{i}),
+ .constant => |val| try renderAnonDeclName(w, val),
+ .decl => |decl| try dg.renderDeclName(w, decl, 0),
+ .identifier => |ident| try w.print("{ }", .{fmtIdent(ident)}),
+ else => unreachable,
+ }
+ }
+
fn writeCValue(dg: *DeclGen, w: anytype, c_value: CValue) !void {
switch (c_value) {
- .none => unreachable,
- .local, .new_local => |i| return w.print("t{d}", .{i}),
- .local_ref => |i| return w.print("&t{d}", .{i}),
- .constant => |val| return renderAnonDeclName(w, val),
- .arg => |i| return w.print("a{d}", .{i}),
- .arg_array => |i| return dg.writeCValueMember(w, .{ .arg = i }, .{ .identifier = "array" }),
- .field => |i| return w.print("f{d}", .{i}),
- .decl => |decl| return dg.renderDeclName(w, decl, 0),
+ .none, .new_local, .local, .local_ref => unreachable,
+ .constant => |val| try renderAnonDeclName(w, val),
+ .arg, .arg_array => unreachable,
+ .field => |i| try w.print("f{d}", .{i}),
+ .decl => |decl| try dg.renderDeclName(w, decl, 0),
.decl_ref => |decl| {
try w.writeByte('&');
- return dg.renderDeclName(w, decl, 0);
+ try dg.renderDeclName(w, decl, 0);
},
- .undef => |ty| return dg.renderValue(w, ty, Value.undef, .Other),
- .identifier => |ident| return w.print("{ }", .{fmtIdent(ident)}),
- .payload_identifier => |ident| return w.print("{ }.{ }", .{
+ .undef => |ty| try dg.renderUndefValue(w, ty, .Other),
+ .identifier => |ident| try w.print("{ }", .{fmtIdent(ident)}),
+ .payload_identifier => |ident| try w.print("{ }.{ }", .{
fmtIdent("payload"),
fmtIdent(ident),
}),
@@ -1911,26 +1975,17 @@ pub const DeclGen = struct {
fn writeCValueDeref(dg: *DeclGen, w: anytype, c_value: CValue) !void {
switch (c_value) {
- .none => unreachable,
- .local, .new_local => |i| return w.print("(*t{d})", .{i}),
- .local_ref => |i| return w.print("t{d}", .{i}),
- .constant => unreachable,
- .arg => |i| return w.print("(*a{d})", .{i}),
- .arg_array => |i| {
- try w.writeAll("(*");
- try dg.writeCValueMember(w, .{ .arg = i }, .{ .identifier = "array" });
- return w.writeByte(')');
- },
- .field => |i| return w.print("f{d}", .{i}),
+ .none, .new_local, .local, .local_ref, .constant, .arg, .arg_array => unreachable,
+ .field => |i| try w.print("f{d}", .{i}),
.decl => |decl| {
try w.writeAll("(*");
try dg.renderDeclName(w, decl, 0);
- return w.writeByte(')');
+ try w.writeByte(')');
},
- .decl_ref => |decl| return dg.renderDeclName(w, decl, 0),
+ .decl_ref => |decl| try dg.renderDeclName(w, decl, 0),
.undef => unreachable,
- .identifier => |ident| return w.print("(*{ })", .{fmtIdent(ident)}),
- .payload_identifier => |ident| return w.print("(*{ }.{ })", .{
+ .identifier => |ident| try w.print("(*{ })", .{fmtIdent(ident)}),
+ .payload_identifier => |ident| try w.print("(*{ }.{ })", .{
fmtIdent("payload"),
fmtIdent(ident),
}),
@@ -1950,12 +2005,12 @@ pub const DeclGen = struct {
fn writeCValueDerefMember(dg: *DeclGen, writer: anytype, c_value: CValue, member: CValue) !void {
switch (c_value) {
- .none, .constant, .field, .undef => unreachable,
- .new_local, .local, .arg, .arg_array, .decl, .identifier, .payload_identifier => {
+ .none, .new_local, .local, .local_ref, .constant, .field, .undef, .arg, .arg_array => unreachable,
+ .decl, .identifier, .payload_identifier => {
try dg.writeCValue(writer, c_value);
try writer.writeAll("->");
},
- .local_ref, .decl_ref => {
+ .decl_ref => {
try dg.writeCValueDeref(writer, c_value);
try writer.writeByte('.');
},
@@ -1969,11 +2024,12 @@ pub const DeclGen = struct {
variable: InternPool.Key.Variable,
fwd_kind: enum { tentative, final },
) !void {
- const decl = dg.module.declPtr(decl_index);
+ const zcu = dg.zcu;
+ const decl = zcu.declPtr(decl_index);
const fwd = dg.fwdDeclWriter();
const is_global = variable.is_extern or dg.declIsGlobal(decl.val);
try fwd.writeAll(if (is_global) "zig_extern " else "static ");
- const maybe_exports = dg.module.decl_exports.get(decl_index);
+ const maybe_exports = zcu.decl_exports.get(decl_index);
const export_weak_linkage = if (maybe_exports) |exports|
exports.items[0].opts.linkage == .weak
else
@@ -1982,14 +2038,14 @@ pub const DeclGen = struct {
if (variable.is_threadlocal) try fwd.writeAll("zig_threadlocal ");
try dg.renderTypeAndName(
fwd,
- decl.typeOf(dg.module),
+ decl.typeOf(zcu),
.{ .decl = decl_index },
CQualifiers.init(.{ .@"const" = variable.is_const }),
decl.alignment,
.complete,
);
mangled: {
- const external_name = dg.module.intern_pool.stringToSlice(if (maybe_exports) |exports|
+ const external_name = zcu.intern_pool.stringToSlice(if (maybe_exports) |exports|
exports.items[0].opts.name
else if (variable.is_extern)
decl.name
@@ -2007,23 +2063,23 @@ pub const DeclGen = struct {
}
fn renderDeclName(dg: *DeclGen, writer: anytype, decl_index: InternPool.DeclIndex, export_index: u32) !void {
- const mod = dg.module;
- const decl = mod.declPtr(decl_index);
+ const zcu = dg.zcu;
+ const decl = zcu.declPtr(decl_index);
- if (mod.decl_exports.get(decl_index)) |exports| {
+ if (zcu.decl_exports.get(decl_index)) |exports| {
try writer.print("{ }", .{
- fmtIdent(mod.intern_pool.stringToSlice(exports.items[export_index].opts.name)),
+ fmtIdent(zcu.intern_pool.stringToSlice(exports.items[export_index].opts.name)),
});
- } else if (decl.getExternDecl(mod).unwrap()) |extern_decl_index| {
+ } else if (decl.getExternDecl(zcu).unwrap()) |extern_decl_index| {
try writer.print("{ }", .{
- fmtIdent(mod.intern_pool.stringToSlice(mod.declPtr(extern_decl_index).name)),
+ fmtIdent(zcu.intern_pool.stringToSlice(zcu.declPtr(extern_decl_index).name)),
});
} else {
// MSVC has a limit of 4095 character token length limit, and fmtIdent can (worst case),
// expand to 3x the length of its input, but let's cut it off at a much shorter limit.
var name: [100]u8 = undefined;
var name_stream = std.io.fixedBufferStream(&name);
- decl.renderFullyQualifiedName(mod, name_stream.writer()) catch |err| switch (err) {
+ decl.renderFullyQualifiedName(zcu, name_stream.writer()) catch |err| switch (err) {
error.NoSpaceLeft => {},
};
try writer.print("{}__{d}", .{
@@ -2033,8 +2089,8 @@ pub const DeclGen = struct {
}
}
- fn renderAnonDeclName(writer: anytype, anon_decl_val: InternPool.Index) !void {
- return writer.print("__anon_{d}", .{@intFromEnum(anon_decl_val)});
+ fn renderAnonDeclName(writer: anytype, anon_decl_val: Value) !void {
+ try writer.print("__anon_{d}", .{@intFromEnum(anon_decl_val.toIntern())});
}
fn renderTypeForBuiltinFnName(dg: *DeclGen, writer: anytype, ty: Type) !void {
@@ -2047,7 +2103,7 @@ pub const DeclGen = struct {
if (cty.isBool())
signAbbrev(.unsigned)
else if (cty.isInteger())
- signAbbrev(cty.signedness(dg.module.getTarget()))
+ signAbbrev(cty.signedness(dg.mod))
else if (cty.isFloat())
@as(u8, 'f')
else if (cty.isPointer())
@@ -2056,7 +2112,7 @@ pub const DeclGen = struct {
return dg.fail("TODO: CBE: implement renderTypeForBuiltinFnName for type {}", .{
cty.tag(),
}),
- if (cty.isFloat()) cty.floatActiveBits(dg.module.getTarget()) else dg.byteSize(cty) * 8,
+ if (cty.isFloat()) cty.floatActiveBits(dg.mod) else dg.byteSize(cty) * 8,
}),
.array => try writer.writeAll("big"),
}
@@ -2065,43 +2121,39 @@ pub const DeclGen = struct {
fn renderBuiltinInfo(dg: *DeclGen, writer: anytype, ty: Type, info: BuiltinInfo) !void {
const cty = try dg.typeToCType(ty, .complete);
const is_big = cty.tag() == .array;
-
switch (info) {
.none => if (!is_big) return,
.bits => {},
}
- const mod = dg.module;
- const int_info = if (ty.isAbiInt(mod)) ty.intInfo(mod) else std.builtin.Type.Int{
+ const zcu = dg.zcu;
+ const int_info = if (ty.isAbiInt(zcu)) ty.intInfo(zcu) else std.builtin.Type.Int{
.signedness = .unsigned,
- .bits = @as(u16, @intCast(ty.bitSize(mod))),
+ .bits = @as(u16, @intCast(ty.bitSize(zcu))),
};
if (is_big) try writer.print(", {}", .{int_info.signedness == .signed});
-
- const bits_ty = if (is_big) Type.u16 else Type.u8;
try writer.print(", {}", .{try dg.fmtIntLiteral(
- bits_ty,
- try mod.intValue(bits_ty, int_info.bits),
+ try zcu.intValue(if (is_big) Type.u16 else Type.u8, int_info.bits),
.FunctionArgument,
)});
}
fn fmtIntLiteral(
dg: *DeclGen,
- ty: Type,
val: Value,
loc: ValueRenderLocation,
) !std.fmt.Formatter(formatIntLiteral) {
- const mod = dg.module;
+ const zcu = dg.zcu;
const kind: CType.Kind = switch (loc) {
.FunctionArgument => .parameter,
.Initializer, .Other => .complete,
.StaticInitializer => .global,
};
+ const ty = val.typeOf(zcu);
return std.fmt.Formatter(formatIntLiteral){ .data = .{
.dg = dg,
- .int_info = ty.intInfo(mod),
+ .int_info = ty.intInfo(zcu),
.kind = kind,
.cty = try dg.typeToCType(ty, kind),
.val = val,
@@ -2133,7 +2185,7 @@ const RenderCTypeTrailing = enum {
}
};
fn renderTypeName(
- mod: *Module,
+ zcu: *Zcu,
w: anytype,
idx: CType.Index,
cty: CType,
@@ -2157,7 +2209,7 @@ fn renderTypeName(
try w.print("{s} {s}{}__{d}", .{
@tagName(tag)["fwd_".len..],
attributes,
- fmtIdent(mod.intern_pool.stringToSlice(mod.declPtr(owner_decl).name)),
+ fmtIdent(zcu.intern_pool.stringToSlice(zcu.declPtr(owner_decl).name)),
@intFromEnum(owner_decl),
});
},
@@ -2166,7 +2218,7 @@ fn renderTypeName(
fn renderTypePrefix(
pass: DeclGen.Pass,
store: CType.Store.Set,
- mod: *Module,
+ zcu: *Zcu,
w: anytype,
idx: CType.Index,
parent_fix: CTypeFix,
@@ -2224,7 +2276,7 @@ fn renderTypePrefix(
const child_trailing = try renderTypePrefix(
pass,
store,
- mod,
+ zcu,
w,
child_idx,
.prefix,
@@ -2247,7 +2299,7 @@ fn renderTypePrefix(
=> {
const child_idx = cty.cast(CType.Payload.Sequence).?.data.elem_type;
const child_trailing =
- try renderTypePrefix(pass, store, mod, w, child_idx, .suffix, qualifiers);
+ try renderTypePrefix(pass, store, zcu, w, child_idx, .suffix, qualifiers);
switch (parent_fix) {
.prefix => {
try w.print("{}(", .{child_trailing});
@@ -2262,12 +2314,12 @@ fn renderTypePrefix(
=> switch (pass) {
.decl => |decl_index| try w.print("decl__{d}_{d}", .{ @intFromEnum(decl_index), idx }),
.anon => |anon_decl| try w.print("anon__{d}_{d}", .{ @intFromEnum(anon_decl), idx }),
- .flush => try renderTypeName(mod, w, idx, cty, ""),
+ .flush => try renderTypeName(zcu, w, idx, cty, ""),
},
.fwd_struct,
.fwd_union,
- => try renderTypeName(mod, w, idx, cty, ""),
+ => try renderTypeName(zcu, w, idx, cty, ""),
.unnamed_struct,
.unnamed_union,
@@ -2278,7 +2330,7 @@ fn renderTypePrefix(
@tagName(tag)["unnamed_".len..],
if (cty.isPacked()) "zig_packed(" else "",
});
- try renderAggregateFields(mod, w, store, cty, 1);
+ try renderAggregateFields(zcu, w, store, cty, 1);
if (cty.isPacked()) try w.writeByte(')');
},
@@ -2291,7 +2343,7 @@ fn renderTypePrefix(
=> return renderTypePrefix(
pass,
store,
- mod,
+ zcu,
w,
cty.cast(CType.Payload.Aggregate).?.data.fwd_decl,
parent_fix,
@@ -2304,7 +2356,7 @@ fn renderTypePrefix(
const child_trailing = try renderTypePrefix(
pass,
store,
- mod,
+ zcu,
w,
cty.cast(CType.Payload.Function).?.data.return_type,
.suffix,
@@ -2331,7 +2383,7 @@ fn renderTypePrefix(
fn renderTypeSuffix(
pass: DeclGen.Pass,
store: CType.Store.Set,
- mod: *Module,
+ zcu: *Zcu,
w: anytype,
idx: CType.Index,
parent_fix: CTypeFix,
@@ -2385,7 +2437,7 @@ fn renderTypeSuffix(
=> try renderTypeSuffix(
pass,
store,
- mod,
+ zcu,
w,
cty.cast(CType.Payload.Child).?.data,
.prefix,
@@ -2404,7 +2456,7 @@ fn renderTypeSuffix(
try renderTypeSuffix(
pass,
store,
- mod,
+ zcu,
w,
cty.cast(CType.Payload.Sequence).?.data.elem_type,
.suffix,
@@ -2444,9 +2496,9 @@ fn renderTypeSuffix(
if (need_comma) try w.writeAll(", ");
need_comma = true;
const trailing =
- try renderTypePrefix(pass, store, mod, w, param_type, .suffix, qualifiers);
+ try renderTypePrefix(pass, store, zcu, w, param_type, .suffix, qualifiers);
if (qualifiers.contains(.@"const")) try w.print("{}a{d}", .{ trailing, param_i });
- try renderTypeSuffix(pass, store, mod, w, param_type, .suffix, .{});
+ try renderTypeSuffix(pass, store, zcu, w, param_type, .suffix, .{});
}
switch (tag) {
.function => {},
@@ -2460,12 +2512,12 @@ fn renderTypeSuffix(
if (!need_comma) try w.writeAll("void");
try w.writeByte(')');
- try renderTypeSuffix(pass, store, mod, w, data.return_type, .suffix, .{});
+ try renderTypeSuffix(pass, store, zcu, w, data.return_type, .suffix, .{});
},
}
}
fn renderAggregateFields(
- mod: *Module,
+ zcu: *Zcu,
writer: anytype,
store: CType.Store.Set,
cty: CType,
@@ -2480,9 +2532,9 @@ fn renderAggregateFields(
.eq => {},
.gt => try writer.print("zig_align({}) ", .{field.alignas.toByteUnits()}),
}
- const trailing = try renderTypePrefix(.flush, store, mod, writer, field.type, .suffix, .{});
+ const trailing = try renderTypePrefix(.flush, store, zcu, writer, field.type, .suffix, .{});
try writer.print("{}{ }", .{ trailing, fmtIdent(mem.span(field.name)) });
- try renderTypeSuffix(.flush, store, mod, writer, field.type, .suffix, .{});
+ try renderTypeSuffix(.flush, store, zcu, writer, field.type, .suffix, .{});
try writer.writeAll(";\n");
}
try writer.writeByteNTimes(' ', indent);
@@ -2490,7 +2542,7 @@ fn renderAggregateFields(
}
pub fn genTypeDecl(
- mod: *Module,
+ zcu: *Zcu,
writer: anytype,
global_store: CType.Store.Set,
global_idx: CType.Index,
@@ -2503,9 +2555,9 @@ pub fn genTypeDecl(
switch (global_cty.tag()) {
.fwd_anon_struct => if (pass != .flush) {
try writer.writeAll("typedef ");
- _ = try renderTypePrefix(.flush, global_store, mod, writer, global_idx, .suffix, .{});
+ _ = try renderTypePrefix(.flush, global_store, zcu, writer, global_idx, .suffix, .{});
try writer.writeByte(' ');
- _ = try renderTypePrefix(pass, decl_store, mod, writer, decl_idx, .suffix, .{});
+ _ = try renderTypePrefix(pass, decl_store, zcu, writer, decl_idx, .suffix, .{});
try writer.writeAll(";\n");
},
@@ -2526,14 +2578,14 @@ pub fn genTypeDecl(
_ = try renderTypePrefix(
.flush,
global_store,
- mod,
+ zcu,
writer,
global_idx,
.suffix,
.{},
);
try writer.writeAll("; /* ");
- try mod.declPtr(owner_decl).renderFullyQualifiedName(mod, writer);
+ try zcu.declPtr(owner_decl).renderFullyQualifiedName(zcu, writer);
try writer.writeAll(" */\n");
},
@@ -2546,14 +2598,14 @@ pub fn genTypeDecl(
=> {
const fwd_idx = global_cty.cast(CType.Payload.Aggregate).?.data.fwd_decl;
try renderTypeName(
- mod,
+ zcu,
writer,
fwd_idx,
global_store.indexToCType(fwd_idx),
if (global_cty.isPacked()) "zig_packed(" else "",
);
try writer.writeByte(' ');
- try renderAggregateFields(mod, writer, global_store, global_cty, 0);
+ try renderAggregateFields(zcu, writer, global_store, global_cty, 0);
if (global_cty.isPacked()) try writer.writeByte(')');
try writer.writeAll(";\n");
},
@@ -2566,30 +2618,30 @@ pub fn genTypeDecl(
}
}
-pub fn genGlobalAsm(mod: *Module, writer: anytype) !void {
- for (mod.global_assembly.values()) |asm_source| {
+pub fn genGlobalAsm(zcu: *Zcu, writer: anytype) !void {
+ for (zcu.global_assembly.values()) |asm_source| {
try writer.print("__asm({s});\n", .{fmtStringLiteral(asm_source, null)});
}
}
pub fn genErrDecls(o: *Object) !void {
- const mod = o.dg.module;
- const ip = &mod.intern_pool;
+ const zcu = o.dg.zcu;
+ const ip = &zcu.intern_pool;
const writer = o.writer();
var max_name_len: usize = 0;
// do not generate an invalid empty enum when the global error set is empty
- if (mod.global_error_set.keys().len > 1) {
+ if (zcu.global_error_set.keys().len > 1) {
try writer.writeAll("enum {\n");
o.indent_writer.pushIndent();
- for (mod.global_error_set.keys()[1..], 1..) |name_nts, value| {
+ for (zcu.global_error_set.keys()[1..], 1..) |name_nts, value| {
const name = ip.stringToSlice(name_nts);
max_name_len = @max(name.len, max_name_len);
- const err_val = try mod.intern(.{ .err = .{
+ const err_val = try zcu.intern(.{ .err = .{
.ty = .anyerror_type,
.name = name_nts,
} });
- try o.dg.renderValue(writer, Type.anyerror, Value.fromInterned(err_val), .Other);
+ try o.dg.renderValue(writer, Value.fromInterned(err_val), .Other);
try writer.print(" = {d}u,\n", .{value});
}
o.indent_writer.popIndent();
@@ -2601,44 +2653,56 @@ pub fn genErrDecls(o: *Object) !void {
defer o.dg.gpa.free(name_buf);
@memcpy(name_buf[0..name_prefix.len], name_prefix);
- for (mod.global_error_set.keys()) |name_ip| {
+ for (zcu.global_error_set.keys()) |name_ip| {
const name = ip.stringToSlice(name_ip);
@memcpy(name_buf[name_prefix.len..][0..name.len], name);
const identifier = name_buf[0 .. name_prefix.len + name.len];
- const name_ty = try mod.arrayType(.{
+ const name_ty = try zcu.arrayType(.{
.len = name.len,
.child = .u8_type,
.sentinel = .zero_u8,
});
- const name_val = try mod.intern(.{ .aggregate = .{
+ const name_val = try zcu.intern(.{ .aggregate = .{
.ty = name_ty.toIntern(),
.storage = .{ .bytes = name },
} });
try writer.writeAll("static ");
- try o.dg.renderTypeAndName(writer, name_ty, .{ .identifier = identifier }, Const, .none, .complete);
+ try o.dg.renderTypeAndName(
+ writer,
+ name_ty,
+ .{ .identifier = identifier },
+ Const,
+ .none,
+ .complete,
+ );
try writer.writeAll(" = ");
- try o.dg.renderValue(writer, name_ty, Value.fromInterned(name_val), .StaticInitializer);
+ try o.dg.renderValue(writer, Value.fromInterned(name_val), .StaticInitializer);
try writer.writeAll(";\n");
}
- const name_array_ty = try mod.arrayType(.{
- .len = mod.global_error_set.count(),
+ const name_array_ty = try zcu.arrayType(.{
+ .len = zcu.global_error_set.count(),
.child = .slice_const_u8_sentinel_0_type,
});
try writer.writeAll("static ");
- try o.dg.renderTypeAndName(writer, name_array_ty, .{ .identifier = array_identifier }, Const, .none, .complete);
+ try o.dg.renderTypeAndName(
+ writer,
+ name_array_ty,
+ .{ .identifier = array_identifier },
+ Const,
+ .none,
+ .complete,
+ );
try writer.writeAll(" = {");
- for (mod.global_error_set.keys(), 0..) |name_nts, value| {
+ for (zcu.global_error_set.keys(), 0..) |name_nts, value| {
const name = ip.stringToSlice(name_nts);
if (value != 0) try writer.writeByte(',');
-
- const len_val = try mod.intValue(Type.usize, name.len);
-
try writer.print("{{" ++ name_prefix ++ "{}, {}}}", .{
- fmtIdent(name), try o.dg.fmtIntLiteral(Type.usize, len_val, .StaticInitializer),
+ fmtIdent(name),
+ try o.dg.fmtIntLiteral(try zcu.intValue(Type.usize, name.len), .StaticInitializer),
});
}
try writer.writeAll("};\n");
@@ -2648,16 +2712,16 @@ fn genExports(o: *Object) !void {
const tracy = trace(@src());
defer tracy.end();
- const mod = o.dg.module;
- const ip = &mod.intern_pool;
+ const zcu = o.dg.zcu;
+ const ip = &zcu.intern_pool;
const decl_index = switch (o.dg.pass) {
.decl => |decl| decl,
.anon, .flush => return,
};
- const decl = mod.declPtr(decl_index);
+ const decl = zcu.declPtr(decl_index);
const fwd = o.dg.fwdDeclWriter();
- const exports = mod.decl_exports.get(decl_index) orelse return;
+ const exports = zcu.decl_exports.get(decl_index) orelse return;
if (exports.items.len < 2) return;
const is_variable_const = switch (ip.indexToKey(decl.val.toIntern())) {
@@ -2685,7 +2749,7 @@ fn genExports(o: *Object) !void {
const export_name = ip.stringToSlice(@"export".opts.name);
try o.dg.renderTypeAndName(
fwd,
- decl.typeOf(mod),
+ decl.typeOf(zcu),
.{ .identifier = export_name },
CQualifiers.init(.{ .@"const" = is_variable_const }),
decl.alignment,
@@ -2708,8 +2772,8 @@ fn genExports(o: *Object) !void {
}
pub fn genLazyFn(o: *Object, lazy_fn: LazyFnMap.Entry) !void {
- const mod = o.dg.module;
- const ip = &mod.intern_pool;
+ const zcu = o.dg.zcu;
+ const ip = &zcu.intern_pool;
const w = o.writer();
const key = lazy_fn.key_ptr.*;
const val = lazy_fn.value_ptr;
@@ -2727,47 +2791,45 @@ pub fn genLazyFn(o: *Object, lazy_fn: LazyFnMap.Entry) !void {
try w.writeByte('(');
try o.dg.renderTypeAndName(w, enum_ty, .{ .identifier = "tag" }, Const, .none, .complete);
try w.writeAll(") {\n switch (tag) {\n");
- const tag_names = enum_ty.enumFields(mod);
+ const tag_names = enum_ty.enumFields(zcu);
for (0..tag_names.len) |tag_index| {
const tag_name = ip.stringToSlice(tag_names.get(ip)[tag_index]);
- const tag_val = try mod.enumValueFieldIndex(enum_ty, @intCast(tag_index));
+ const tag_val = try zcu.enumValueFieldIndex(enum_ty, @intCast(tag_index));
- const int_val = try tag_val.intFromEnum(enum_ty, mod);
-
- const name_ty = try mod.arrayType(.{
+ const name_ty = try zcu.arrayType(.{
.len = tag_name.len,
.child = .u8_type,
.sentinel = .zero_u8,
});
- const name_val = try mod.intern(.{ .aggregate = .{
+ const name_val = try zcu.intern(.{ .aggregate = .{
.ty = name_ty.toIntern(),
.storage = .{ .bytes = tag_name },
} });
- const len_val = try mod.intValue(Type.usize, tag_name.len);
try w.print(" case {}: {{\n static ", .{
- try o.dg.fmtIntLiteral(enum_ty, int_val, .Other),
+ try o.dg.fmtIntLiteral(try tag_val.intFromEnum(enum_ty, zcu), .Other),
});
try o.dg.renderTypeAndName(w, name_ty, .{ .identifier = "name" }, Const, .none, .complete);
try w.writeAll(" = ");
- try o.dg.renderValue(w, name_ty, Value.fromInterned(name_val), .Initializer);
+ try o.dg.renderValue(w, Value.fromInterned(name_val), .Initializer);
try w.writeAll(";\n return (");
try o.dg.renderType(w, name_slice_ty);
try w.print("){{{}, {}}};\n", .{
- fmtIdent("name"), try o.dg.fmtIntLiteral(Type.usize, len_val, .Other),
+ fmtIdent("name"),
+ try o.dg.fmtIntLiteral(try zcu.intValue(Type.usize, tag_name.len), .Other),
});
try w.writeAll(" }\n");
}
try w.writeAll(" }\n while (");
- try o.dg.renderValue(w, Type.bool, Value.true, .Other);
+ try o.dg.renderValue(w, Value.true, .Other);
try w.writeAll(") ");
_ = try airBreakpoint(w);
try w.writeAll("}\n");
},
.never_tail, .never_inline => |fn_decl_index| {
- const fn_decl = mod.declPtr(fn_decl_index);
- const fn_cty = try o.dg.typeToCType(fn_decl.typeOf(mod), .complete);
+ const fn_decl = zcu.declPtr(fn_decl_index);
+ const fn_cty = try o.dg.typeToCType(fn_decl.typeOf(zcu), .complete);
const fn_info = fn_cty.cast(CType.Payload.Function).?.data;
const fwd_decl_writer = o.dg.fwdDeclWriter();
@@ -2799,10 +2861,10 @@ pub fn genFunc(f: *Function) !void {
defer tracy.end();
const o = &f.object;
- const mod = o.dg.module;
+ const zcu = o.dg.zcu;
const gpa = o.dg.gpa;
const decl_index = o.dg.pass.decl;
- const decl = mod.declPtr(decl_index);
+ const decl = zcu.declPtr(decl_index);
o.code_header = std.ArrayList(u8).init(gpa);
defer o.code_header.deinit();
@@ -2811,7 +2873,7 @@ pub fn genFunc(f: *Function) !void {
const fwd_decl_writer = o.dg.fwdDeclWriter();
try fwd_decl_writer.writeAll(if (is_global) "zig_extern " else "static ");
- if (mod.decl_exports.get(decl_index)) |exports|
+ if (zcu.decl_exports.get(decl_index)) |exports|
if (exports.items[0].opts.linkage == .weak) try fwd_decl_writer.writeAll("zig_weak_linkage_fn ");
try o.dg.renderFunctionSignature(fwd_decl_writer, decl_index, .forward, .{ .export_index = 0 });
try fwd_decl_writer.writeAll(";\n");
@@ -2819,6 +2881,8 @@ pub fn genFunc(f: *Function) !void {
try o.indent_writer.insertNewline();
if (!is_global) try o.writer().writeAll("static ");
+ if (zcu.intern_pool.stringToSliceUnwrap(decl.@"linksection")) |s|
+ try o.writer().print("zig_linksection_fn({s}) ", .{fmtStringLiteral(s, null)});
try o.dg.renderFunctionSignature(o.writer(), decl_index, .complete, .{ .export_index = 0 });
try o.writer().writeByte(' ');
@@ -2867,7 +2931,7 @@ pub fn genFunc(f: *Function) !void {
for (free_locals.values()) |list| {
for (list.keys()) |local_index| {
const local = f.locals.items[local_index];
- try o.dg.renderCTypeAndName(w, local.cty_idx, .{ .local = local_index }, .{}, local.alignas);
+ try o.dg.renderCTypeAndName(w, local.cty_idx, .{ .local = local_index }, .{}, local.flags.alignas);
try w.writeAll(";\n ");
}
}
@@ -2884,43 +2948,41 @@ pub fn genDecl(o: *Object) !void {
const tracy = trace(@src());
defer tracy.end();
- const mod = o.dg.module;
+ const zcu = o.dg.zcu;
const decl_index = o.dg.pass.decl;
- const decl = mod.declPtr(decl_index);
- const decl_val = decl.val;
- const decl_ty = decl_val.typeOf(mod);
+ const decl = zcu.declPtr(decl_index);
+ const decl_ty = decl.typeOf(zcu);
- if (!decl_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) return;
- if (decl_val.getExternFunc(mod)) |_| {
+ if (!decl_ty.isFnOrHasRuntimeBitsIgnoreComptime(zcu)) return;
+ if (decl.val.getExternFunc(zcu)) |_| {
const fwd_decl_writer = o.dg.fwdDeclWriter();
try fwd_decl_writer.writeAll("zig_extern ");
try o.dg.renderFunctionSignature(fwd_decl_writer, decl_index, .forward, .{ .export_index = 0 });
try fwd_decl_writer.writeAll(";\n");
try genExports(o);
- } else if (decl_val.getVariable(mod)) |variable| {
+ } else if (decl.val.getVariable(zcu)) |variable| {
try o.dg.renderFwdDecl(decl_index, variable, .final);
try genExports(o);
if (variable.is_extern) return;
- const is_global = variable.is_extern or o.dg.declIsGlobal(decl_val);
+ const is_global = variable.is_extern or o.dg.declIsGlobal(decl.val);
const w = o.writer();
if (!is_global) try w.writeAll("static ");
if (variable.is_weak_linkage) try w.writeAll("zig_weak_linkage ");
if (variable.is_threadlocal) try w.writeAll("zig_threadlocal ");
- if (mod.intern_pool.stringToSliceUnwrap(decl.@"linksection")) |s|
- try w.print("zig_linksection(\"{s}\", ", .{s});
+ if (zcu.intern_pool.stringToSliceUnwrap(decl.@"linksection")) |s|
+ try w.print("zig_linksection({s}) ", .{fmtStringLiteral(s, null)});
const decl_c_value = .{ .decl = decl_index };
try o.dg.renderTypeAndName(w, decl_ty, decl_c_value, .{}, decl.alignment, .complete);
- if (decl.@"linksection" != .none) try w.writeAll(", read, write)");
try w.writeAll(" = ");
- try o.dg.renderValue(w, decl_ty, Value.fromInterned(variable.init), .StaticInitializer);
+ try o.dg.renderValue(w, Value.fromInterned(variable.init), .StaticInitializer);
try w.writeByte(';');
try o.indent_writer.insertNewline();
} else {
- const is_global = o.dg.module.decl_exports.contains(decl_index);
+ const is_global = o.dg.zcu.decl_exports.contains(decl_index);
const decl_c_value = .{ .decl = decl_index };
- try genDeclValue(o, decl_val, is_global, decl_c_value, decl.alignment, decl.@"linksection");
+ try genDeclValue(o, decl.val, is_global, decl_c_value, decl.alignment, decl.@"linksection");
}
}
@@ -2930,19 +2992,19 @@ pub fn genDeclValue(
is_global: bool,
decl_c_value: CValue,
alignment: Alignment,
- link_section: InternPool.OptionalNullTerminatedString,
+ @"linksection": InternPool.OptionalNullTerminatedString,
) !void {
- const mod = o.dg.module;
+ const zcu = o.dg.zcu;
const fwd_decl_writer = o.dg.fwdDeclWriter();
- const ty = val.typeOf(mod);
+ const ty = val.typeOf(zcu);
try fwd_decl_writer.writeAll(if (is_global) "zig_extern " else "static ");
try o.dg.renderTypeAndName(fwd_decl_writer, ty, decl_c_value, Const, alignment, .complete);
switch (o.dg.pass) {
.decl => |decl_index| {
- if (mod.decl_exports.get(decl_index)) |exports| {
- const export_name = mod.intern_pool.stringToSlice(exports.items[0].opts.name);
+ if (zcu.decl_exports.get(decl_index)) |exports| {
+ const export_name = zcu.intern_pool.stringToSlice(exports.items[0].opts.name);
if (isMangledIdent(export_name, true)) {
try fwd_decl_writer.print(" zig_mangled_final({ }, {s})", .{
fmtIdent(export_name), fmtStringLiteral(export_name, null),
@@ -2958,13 +3020,11 @@ pub fn genDeclValue(
const w = o.writer();
if (!is_global) try w.writeAll("static ");
-
- if (mod.intern_pool.stringToSliceUnwrap(link_section)) |s|
- try w.print("zig_linksection(\"{s}\", ", .{s});
+ if (zcu.intern_pool.stringToSliceUnwrap(@"linksection")) |s|
+ try w.print("zig_linksection({s}) ", .{fmtStringLiteral(s, null)});
try o.dg.renderTypeAndName(w, ty, decl_c_value, Const, alignment, .complete);
- if (link_section != .none) try w.writeAll(", read)");
try w.writeAll(" = ");
- try o.dg.renderValue(w, ty, val, .StaticInitializer);
+ try o.dg.renderValue(w, val, .StaticInitializer);
try w.writeAll(";\n");
}
@@ -2972,12 +3032,12 @@ pub fn genHeader(dg: *DeclGen) error{ AnalysisFail, OutOfMemory }!void {
const tracy = trace(@src());
defer tracy.end();
- const mod = dg.module;
+ const zcu = dg.zcu;
const decl_index = dg.pass.decl;
- const decl = mod.declPtr(decl_index);
+ const decl = zcu.declPtr(decl_index);
const writer = dg.fwdDeclWriter();
- switch (decl.val.typeOf(mod).zigTypeTag(mod)) {
+ switch (decl.typeOf(zcu).zigTypeTag(zcu)) {
.Fn => if (dg.declIsGlobal(decl.val)) {
try writer.writeAll("zig_extern ");
try dg.renderFunctionSignature(writer, dg.pass.decl, .complete, .{ .export_index = 0 });
@@ -3060,8 +3120,8 @@ fn genBodyResolveState(f: *Function, inst: Air.Inst.Index, leading_deaths: []con
}
fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutOfMemory }!void {
- const mod = f.object.dg.module;
- const ip = &mod.intern_pool;
+ const zcu = f.object.dg.zcu;
+ const ip = &zcu.intern_pool;
const air_tags = f.air.instructions.items(.tag);
for (body) |inst| {
@@ -3096,10 +3156,10 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail,
.div_trunc, .div_exact => try airBinOp(f, inst, "/", "div_trunc", .none),
.rem => blk: {
const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
- const lhs_scalar_ty = f.typeOf(bin_op.lhs).scalarType(mod);
+ const lhs_scalar_ty = f.typeOf(bin_op.lhs).scalarType(zcu);
// For binary operations @TypeOf(lhs)==@TypeOf(rhs),
// so we only check one.
- break :blk if (lhs_scalar_ty.isInt(mod))
+ break :blk if (lhs_scalar_ty.isInt(zcu))
try airBinOp(f, inst, "%", "rem", .none)
else
try airBinFloatOp(f, inst, "fmod");
@@ -3359,10 +3419,10 @@ fn airSliceField(f: *Function, inst: Air.Inst.Index, is_ptr: bool, field_name: [
}
fn airPtrElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const inst_ty = f.typeOfIndex(inst);
const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
- if (!inst_ty.hasRuntimeBitsIgnoreComptime(mod)) {
+ if (!inst_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
return .none;
}
@@ -3385,14 +3445,17 @@ fn airPtrElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
}
fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;
const inst_ty = f.typeOfIndex(inst);
const ptr_ty = f.typeOf(bin_op.lhs);
- const elem_ty = ptr_ty.childType(mod);
- const elem_has_bits = elem_ty.hasRuntimeBitsIgnoreComptime(mod);
+ const ptr_align = ptr_ty.ptrAlignment(zcu);
+ const elem_ty = ptr_ty.elemType2(zcu);
+ const elem_align = elem_ty.abiAlignment(zcu);
+ const is_under_aligned = ptr_align.compareStrict(.lt, elem_align);
+ const elem_has_bits = elem_ty.hasRuntimeBitsIgnoreComptime(zcu);
const ptr = try f.resolveInst(bin_op.lhs);
const index = try f.resolveInst(bin_op.rhs);
@@ -3407,13 +3470,22 @@ fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
try f.renderType(writer, inst_ty);
try writer.writeByte(')');
if (elem_has_bits) try writer.writeByte('&');
- if (elem_has_bits and ptr_ty.ptrSize(mod) == .One) {
+ if (elem_has_bits and ptr_ty.ptrSize(zcu) == .One and !is_under_aligned) {
// It's a pointer to an array, so we need to de-reference.
try f.writeCValueDeref(writer, ptr);
} else try f.writeCValue(writer, ptr, .Other);
if (elem_has_bits) {
try writer.writeByte('[');
try f.writeCValue(writer, index, .Other);
+ if (is_under_aligned) {
+ const factor = @divExact(elem_align.toByteUnitsOptional().?, @min(
+ ptr_align.toByteUnitsOptional().?,
+ f.object.dg.mod.resolved_target.result.maxIntAlignment(),
+ ));
+ try writer.print(" * {}", .{
+ try f.fmtIntLiteral(try zcu.intValue(Type.usize, factor)),
+ });
+ }
try writer.writeByte(']');
}
try a.end(f, writer);
@@ -3421,10 +3493,10 @@ fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
}
fn airSliceElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const inst_ty = f.typeOfIndex(inst);
const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
- if (!inst_ty.hasRuntimeBitsIgnoreComptime(mod)) {
+ if (!inst_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
return .none;
}
@@ -3447,14 +3519,14 @@ fn airSliceElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
}
fn airSliceElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;
const inst_ty = f.typeOfIndex(inst);
const slice_ty = f.typeOf(bin_op.lhs);
- const elem_ty = slice_ty.elemType2(mod);
- const elem_has_bits = elem_ty.hasRuntimeBitsIgnoreComptime(mod);
+ const elem_ty = slice_ty.elemType2(zcu);
+ const elem_has_bits = elem_ty.hasRuntimeBitsIgnoreComptime(zcu);
const slice = try f.resolveInst(bin_op.lhs);
const index = try f.resolveInst(bin_op.rhs);
@@ -3477,10 +3549,10 @@ fn airSliceElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
}
fn airArrayElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const inst_ty = f.typeOfIndex(inst);
- if (!inst_ty.hasRuntimeBitsIgnoreComptime(mod)) {
+ if (!inst_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
return .none;
}
@@ -3503,33 +3575,33 @@ fn airArrayElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
}
fn airAlloc(f: *Function, inst: Air.Inst.Index) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const inst_ty = f.typeOfIndex(inst);
- const elem_type = inst_ty.childType(mod);
- if (!elem_type.isFnOrHasRuntimeBitsIgnoreComptime(mod)) return .{ .undef = inst_ty };
+ const elem_type = inst_ty.childType(zcu);
+ if (!elem_type.isFnOrHasRuntimeBitsIgnoreComptime(zcu)) return .{ .undef = inst_ty };
const local = try f.allocLocalValue(
elem_type,
- inst_ty.ptrAlignment(mod),
+ inst_ty.ptrAlignment(zcu),
);
log.debug("%{d}: allocated unfreeable t{d}", .{ inst, local.new_local });
- const gpa = f.object.dg.module.gpa;
+ const gpa = f.object.dg.zcu.gpa;
try f.allocs.put(gpa, local.new_local, true);
return .{ .local_ref = local.new_local };
}
fn airRetPtr(f: *Function, inst: Air.Inst.Index) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const inst_ty = f.typeOfIndex(inst);
- const elem_ty = inst_ty.childType(mod);
- if (!elem_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) return .{ .undef = inst_ty };
+ const elem_ty = inst_ty.childType(zcu);
+ if (!elem_ty.isFnOrHasRuntimeBitsIgnoreComptime(zcu)) return .{ .undef = inst_ty };
const local = try f.allocLocalValue(
elem_ty,
- inst_ty.ptrAlignment(mod),
+ inst_ty.ptrAlignment(zcu),
);
log.debug("%{d}: allocated unfreeable t{d}", .{ inst, local.new_local });
- const gpa = f.object.dg.module.gpa;
+ const gpa = f.object.dg.zcu.gpa;
try f.allocs.put(gpa, local.new_local, true);
return .{ .local_ref = local.new_local };
}
@@ -3559,15 +3631,15 @@ fn airArg(f: *Function, inst: Air.Inst.Index) !CValue {
}
fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const ptr_ty = f.typeOf(ty_op.operand);
- const ptr_scalar_ty = ptr_ty.scalarType(mod);
- const ptr_info = ptr_scalar_ty.ptrInfo(mod);
+ const ptr_scalar_ty = ptr_ty.scalarType(zcu);
+ const ptr_info = ptr_scalar_ty.ptrInfo(zcu);
const src_ty = Type.fromInterned(ptr_info.child);
- if (!src_ty.hasRuntimeBitsIgnoreComptime(mod)) {
+ if (!src_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
try reap(f, inst, &.{ty_op.operand});
return .none;
}
@@ -3577,10 +3649,10 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
try reap(f, inst, &.{ty_op.operand});
const is_aligned = if (ptr_info.flags.alignment != .none)
- ptr_info.flags.alignment.compare(.gte, src_ty.abiAlignment(mod))
+ ptr_info.flags.alignment.compare(.gte, src_ty.abiAlignment(zcu))
else
true;
- const is_array = lowersToArray(src_ty, mod);
+ const is_array = lowersToArray(src_ty, zcu);
const need_memcpy = !is_aligned or is_array;
const writer = f.object.writer();
@@ -3600,12 +3672,12 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
try writer.writeAll("))");
} else if (ptr_info.packed_offset.host_size > 0 and ptr_info.flags.vector_index == .none) {
const host_bits: u16 = ptr_info.packed_offset.host_size * 8;
- const host_ty = try mod.intType(.unsigned, host_bits);
+ const host_ty = try zcu.intType(.unsigned, host_bits);
- const bit_offset_ty = try mod.intType(.unsigned, Type.smallestUnsignedBits(host_bits - 1));
- const bit_offset_val = try mod.intValue(bit_offset_ty, ptr_info.packed_offset.bit_offset);
+ const bit_offset_ty = try zcu.intType(.unsigned, Type.smallestUnsignedBits(host_bits - 1));
+ const bit_offset_val = try zcu.intValue(bit_offset_ty, ptr_info.packed_offset.bit_offset);
- const field_ty = try mod.intType(.unsigned, @as(u16, @intCast(src_ty.bitSize(mod))));
+ const field_ty = try zcu.intType(.unsigned, @as(u16, @intCast(src_ty.bitSize(zcu))));
try f.writeCValue(writer, local, .Other);
try v.elem(f, writer);
@@ -3616,9 +3688,9 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
try writer.writeAll("((");
try f.renderType(writer, field_ty);
try writer.writeByte(')');
- const cant_cast = host_ty.isInt(mod) and host_ty.bitSize(mod) > 64;
+ const cant_cast = host_ty.isInt(zcu) and host_ty.bitSize(zcu) > 64;
if (cant_cast) {
- if (field_ty.bitSize(mod) > 64) return f.fail("TODO: C backend: implement casting between types > 64 bits", .{});
+ if (field_ty.bitSize(zcu) > 64) return f.fail("TODO: C backend: implement casting between types > 64 bits", .{});
try writer.writeAll("zig_lo_");
try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty);
try writer.writeByte('(');
@@ -3628,7 +3700,7 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
try writer.writeByte('(');
try f.writeCValueDeref(writer, operand);
try v.elem(f, writer);
- try writer.print(", {})", .{try f.fmtIntLiteral(bit_offset_ty, bit_offset_val)});
+ try writer.print(", {})", .{try f.fmtIntLiteral(bit_offset_val)});
if (cant_cast) try writer.writeByte(')');
try f.object.dg.renderBuiltinInfo(writer, field_ty, .bits);
try writer.writeByte(')');
@@ -3646,22 +3718,22 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
}
fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const writer = f.object.writer();
const op_inst = un_op.toIndex();
const op_ty = f.typeOf(un_op);
- const ret_ty = if (is_ptr) op_ty.childType(mod) else op_ty;
- const lowered_ret_ty = try lowerFnRetTy(ret_ty, mod);
+ const ret_ty = if (is_ptr) op_ty.childType(zcu) else op_ty;
+ const lowered_ret_ty = try lowerFnRetTy(ret_ty, zcu);
if (op_inst != null and f.air.instructions.items(.tag)[@intFromEnum(op_inst.?)] == .call_always_tail) {
try reap(f, inst, &.{un_op});
_ = try airCall(f, op_inst.?, .always_tail);
- } else if (lowered_ret_ty.hasRuntimeBitsIgnoreComptime(mod)) {
+ } else if (lowered_ret_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
const operand = try f.resolveInst(un_op);
try reap(f, inst, &.{un_op});
var deref = is_ptr;
- const is_array = lowersToArray(ret_ty, mod);
+ const is_array = lowersToArray(ret_ty, zcu);
const ret_val = if (is_array) ret_val: {
const array_local = try f.allocLocal(inst, lowered_ret_ty);
try writer.writeAll("memcpy(");
@@ -3696,16 +3768,16 @@ fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue {
}
fn airIntCast(f: *Function, inst: Air.Inst.Index) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const operand = try f.resolveInst(ty_op.operand);
try reap(f, inst, &.{ty_op.operand});
const inst_ty = f.typeOfIndex(inst);
- const inst_scalar_ty = inst_ty.scalarType(mod);
+ const inst_scalar_ty = inst_ty.scalarType(zcu);
const operand_ty = f.typeOf(ty_op.operand);
- const scalar_ty = operand_ty.scalarType(mod);
+ const scalar_ty = operand_ty.scalarType(zcu);
const writer = f.object.writer();
const local = try f.allocLocal(inst, inst_ty);
@@ -3722,20 +3794,20 @@ fn airIntCast(f: *Function, inst: Air.Inst.Index) !CValue {
}
fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const operand = try f.resolveInst(ty_op.operand);
try reap(f, inst, &.{ty_op.operand});
const inst_ty = f.typeOfIndex(inst);
- const inst_scalar_ty = inst_ty.scalarType(mod);
- const dest_int_info = inst_scalar_ty.intInfo(mod);
+ const inst_scalar_ty = inst_ty.scalarType(zcu);
+ const dest_int_info = inst_scalar_ty.intInfo(zcu);
const dest_bits = dest_int_info.bits;
const dest_c_bits = toCIntBits(dest_int_info.bits) orelse
return f.fail("TODO: C backend: implement integer types larger than 128 bits", .{});
const operand_ty = f.typeOf(ty_op.operand);
- const scalar_ty = operand_ty.scalarType(mod);
- const scalar_int_info = scalar_ty.intInfo(mod);
+ const scalar_ty = operand_ty.scalarType(zcu);
+ const scalar_int_info = scalar_ty.intInfo(zcu);
const writer = f.object.writer();
const local = try f.allocLocal(inst, inst_ty);
@@ -3763,18 +3835,19 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {
try v.elem(f, writer);
} else switch (dest_int_info.signedness) {
.unsigned => {
- const mask_val = try inst_scalar_ty.maxIntScalar(mod, scalar_ty);
try writer.writeAll("zig_and_");
try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty);
try writer.writeByte('(');
try f.writeCValue(writer, operand, .FunctionArgument);
try v.elem(f, writer);
- try writer.print(", {x})", .{try f.fmtIntLiteral(scalar_ty, mask_val)});
+ try writer.print(", {x})", .{
+ try f.fmtIntLiteral(try inst_scalar_ty.maxIntScalar(zcu, scalar_ty)),
+ });
},
.signed => {
const c_bits = toCIntBits(scalar_int_info.bits) orelse
return f.fail("TODO: C backend: implement integer types larger than 128 bits", .{});
- const shift_val = try mod.intValue(Type.u8, c_bits - dest_bits);
+ const shift_val = try zcu.intValue(Type.u8, c_bits - dest_bits);
try writer.writeAll("zig_shr_");
try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty);
@@ -3792,9 +3865,9 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {
try f.writeCValue(writer, operand, .FunctionArgument);
try v.elem(f, writer);
if (c_bits == 128) try writer.writeByte(')');
- try writer.print(", {})", .{try f.fmtIntLiteral(Type.u8, shift_val)});
+ try writer.print(", {})", .{try f.fmtIntLiteral(shift_val)});
if (c_bits == 128) try writer.writeByte(')');
- try writer.print(", {})", .{try f.fmtIntLiteral(Type.u8, shift_val)});
+ try writer.print(", {})", .{try f.fmtIntLiteral(shift_val)});
},
}
@@ -3821,18 +3894,18 @@ fn airIntFromBool(f: *Function, inst: Air.Inst.Index) !CValue {
}
fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
// *a = b;
const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const ptr_ty = f.typeOf(bin_op.lhs);
- const ptr_scalar_ty = ptr_ty.scalarType(mod);
- const ptr_info = ptr_scalar_ty.ptrInfo(mod);
+ const ptr_scalar_ty = ptr_ty.scalarType(zcu);
+ const ptr_info = ptr_scalar_ty.ptrInfo(zcu);
const ptr_val = try f.resolveInst(bin_op.lhs);
const src_ty = f.typeOf(bin_op.rhs);
- const val_is_undef = if (try f.air.value(bin_op.rhs, mod)) |v| v.isUndefDeep(mod) else false;
+ const val_is_undef = if (try f.air.value(bin_op.rhs, zcu)) |v| v.isUndefDeep(zcu) else false;
if (val_is_undef) {
try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
@@ -3848,10 +3921,10 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
}
const is_aligned = if (ptr_info.flags.alignment != .none)
- ptr_info.flags.alignment.compare(.gte, src_ty.abiAlignment(mod))
+ ptr_info.flags.alignment.compare(.gte, src_ty.abiAlignment(zcu))
else
true;
- const is_array = lowersToArray(Type.fromInterned(ptr_info.child), mod);
+ const is_array = lowersToArray(Type.fromInterned(ptr_info.child), zcu);
const need_memcpy = !is_aligned or is_array;
const src_val = try f.resolveInst(bin_op.rhs);
@@ -3863,7 +3936,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
if (need_memcpy) {
// For this memcpy to safely work we need the rhs to have the same
// underlying type as the lhs (i.e. they must both be arrays of the same underlying type).
- assert(src_ty.eql(Type.fromInterned(ptr_info.child), f.object.dg.module));
+ assert(src_ty.eql(Type.fromInterned(ptr_info.child), f.object.dg.zcu));
// If the source is a constant, writeCValue will emit a brace initialization
// so work around this by initializing into new local.
@@ -3893,12 +3966,12 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
}
} else if (ptr_info.packed_offset.host_size > 0 and ptr_info.flags.vector_index == .none) {
const host_bits = ptr_info.packed_offset.host_size * 8;
- const host_ty = try mod.intType(.unsigned, host_bits);
+ const host_ty = try zcu.intType(.unsigned, host_bits);
- const bit_offset_ty = try mod.intType(.unsigned, Type.smallestUnsignedBits(host_bits - 1));
- const bit_offset_val = try mod.intValue(bit_offset_ty, ptr_info.packed_offset.bit_offset);
+ const bit_offset_ty = try zcu.intType(.unsigned, Type.smallestUnsignedBits(host_bits - 1));
+ const bit_offset_val = try zcu.intValue(bit_offset_ty, ptr_info.packed_offset.bit_offset);
- const src_bits = src_ty.bitSize(mod);
+ const src_bits = src_ty.bitSize(zcu);
const ExpectedContents = [BigInt.Managed.default_capacity]BigIntLimb;
var stack align(@alignOf(ExpectedContents)) =
@@ -3911,7 +3984,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
try mask.shiftLeft(&mask, ptr_info.packed_offset.bit_offset);
try mask.bitNotWrap(&mask, .unsigned, host_bits);
- const mask_val = try mod.intValue_big(host_ty, mask.toConst());
+ const mask_val = try zcu.intValue_big(host_ty, mask.toConst());
try f.writeCValueDeref(writer, ptr_val);
try v.elem(f, writer);
@@ -3922,12 +3995,12 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
try writer.writeByte('(');
try f.writeCValueDeref(writer, ptr_val);
try v.elem(f, writer);
- try writer.print(", {x}), zig_shl_", .{try f.fmtIntLiteral(host_ty, mask_val)});
+ try writer.print(", {x}), zig_shl_", .{try f.fmtIntLiteral(mask_val)});
try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty);
try writer.writeByte('(');
- const cant_cast = host_ty.isInt(mod) and host_ty.bitSize(mod) > 64;
+ const cant_cast = host_ty.isInt(zcu) and host_ty.bitSize(zcu) > 64;
if (cant_cast) {
- if (src_ty.bitSize(mod) > 64) return f.fail("TODO: C backend: implement casting between types > 64 bits", .{});
+ if (src_ty.bitSize(zcu) > 64) return f.fail("TODO: C backend: implement casting between types > 64 bits", .{});
try writer.writeAll("zig_make_");
try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty);
try writer.writeAll("(0, ");
@@ -3937,7 +4010,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
try writer.writeByte(')');
}
- if (src_ty.isPtrAtRuntime(mod)) {
+ if (src_ty.isPtrAtRuntime(zcu)) {
try writer.writeByte('(');
try f.renderType(writer, Type.usize);
try writer.writeByte(')');
@@ -3945,7 +4018,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
try f.writeCValue(writer, src_val, .Other);
try v.elem(f, writer);
if (cant_cast) try writer.writeByte(')');
- try writer.print(", {}))", .{try f.fmtIntLiteral(bit_offset_ty, bit_offset_val)});
+ try writer.print(", {}))", .{try f.fmtIntLiteral(bit_offset_val)});
} else {
try f.writeCValueDeref(writer, ptr_val);
try v.elem(f, writer);
@@ -3960,7 +4033,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
}
fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info: BuiltinInfo) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;
@@ -3970,7 +4043,7 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info:
const inst_ty = f.typeOfIndex(inst);
const operand_ty = f.typeOf(bin_op.lhs);
- const scalar_ty = operand_ty.scalarType(mod);
+ const scalar_ty = operand_ty.scalarType(zcu);
const w = f.object.writer();
const local = try f.allocLocal(inst, inst_ty);
@@ -3998,11 +4071,11 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info:
}
fn airNot(f: *Function, inst: Air.Inst.Index) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const operand_ty = f.typeOf(ty_op.operand);
- const scalar_ty = operand_ty.scalarType(mod);
- if (scalar_ty.ip_index != .bool_type) return try airUnBuiltinCall(f, inst, "not", .bits);
+ const scalar_ty = operand_ty.scalarType(zcu);
+ if (scalar_ty.toIntern() != .bool_type) return try airUnBuiltinCall(f, inst, "not", .bits);
const op = try f.resolveInst(ty_op.operand);
try reap(f, inst, &.{ty_op.operand});
@@ -4031,11 +4104,11 @@ fn airBinOp(
operation: []const u8,
info: BuiltinInfo,
) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const operand_ty = f.typeOf(bin_op.lhs);
- const scalar_ty = operand_ty.scalarType(mod);
- if ((scalar_ty.isInt(mod) and scalar_ty.bitSize(mod) > 64) or scalar_ty.isRuntimeFloat())
+ const scalar_ty = operand_ty.scalarType(zcu);
+ if ((scalar_ty.isInt(zcu) and scalar_ty.bitSize(zcu) > 64) or scalar_ty.isRuntimeFloat())
return try airBinBuiltinCall(f, inst, operation, info);
const lhs = try f.resolveInst(bin_op.lhs);
@@ -4069,12 +4142,12 @@ fn airCmpOp(
data: anytype,
operator: std.math.CompareOperator,
) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const lhs_ty = f.typeOf(data.lhs);
- const scalar_ty = lhs_ty.scalarType(mod);
+ const scalar_ty = lhs_ty.scalarType(zcu);
- const scalar_bits = scalar_ty.bitSize(mod);
- if (scalar_ty.isInt(mod) and scalar_bits > 64)
+ const scalar_bits = scalar_ty.bitSize(zcu);
+ if (scalar_ty.isInt(zcu) and scalar_bits > 64)
return airCmpBuiltinCall(
f,
inst,
@@ -4092,7 +4165,7 @@ fn airCmpOp(
try reap(f, inst, &.{ data.lhs, data.rhs });
const rhs_ty = f.typeOf(data.rhs);
- const need_cast = lhs_ty.isSinglePointer(mod) or rhs_ty.isSinglePointer(mod);
+ const need_cast = lhs_ty.isSinglePointer(zcu) or rhs_ty.isSinglePointer(zcu);
const writer = f.object.writer();
const local = try f.allocLocal(inst, inst_ty);
const v = try Vectorize.start(f, inst, writer, lhs_ty);
@@ -4117,12 +4190,12 @@ fn airEquality(
inst: Air.Inst.Index,
operator: std.math.CompareOperator,
) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const operand_ty = f.typeOf(bin_op.lhs);
- const operand_bits = operand_ty.bitSize(mod);
- if (operand_ty.isInt(mod) and operand_bits > 64)
+ const operand_bits = operand_ty.bitSize(zcu);
+ if (operand_ty.isInt(zcu) and operand_bits > 64)
return airCmpBuiltinCall(
f,
inst,
@@ -4145,7 +4218,7 @@ fn airEquality(
try f.writeCValue(writer, local, .Other);
try a.assign(f, writer);
- if (operand_ty.zigTypeTag(mod) == .Optional and !operand_ty.optionalReprIsPayload(mod)) {
+ if (operand_ty.zigTypeTag(zcu) == .Optional and !operand_ty.optionalReprIsPayload(zcu)) {
try f.writeCValueMember(writer, lhs, .{ .identifier = "is_null" });
try writer.writeAll(" || ");
try f.writeCValueMember(writer, rhs, .{ .identifier = "is_null" });
@@ -4184,7 +4257,7 @@ fn airCmpLtErrorsLen(f: *Function, inst: Air.Inst.Index) !CValue {
}
fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;
@@ -4193,8 +4266,8 @@ fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue {
try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
const inst_ty = f.typeOfIndex(inst);
- const inst_scalar_ty = inst_ty.scalarType(mod);
- const elem_ty = inst_scalar_ty.elemType2(mod);
+ const inst_scalar_ty = inst_ty.scalarType(zcu);
+ const elem_ty = inst_scalar_ty.elemType2(zcu);
const local = try f.allocLocal(inst, inst_ty);
const writer = f.object.writer();
@@ -4203,7 +4276,7 @@ fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue {
try v.elem(f, writer);
try writer.writeAll(" = ");
- if (elem_ty.hasRuntimeBitsIgnoreComptime(mod)) {
+ if (elem_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
// We must convert to and from integer types to prevent UB if the operation
// results in a NULL pointer, or if LHS is NULL. The operation is only UB
// if the result is NULL and then dereferenced.
@@ -4232,13 +4305,13 @@ fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue {
}
fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: u8, operation: []const u8) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const inst_ty = f.typeOfIndex(inst);
- const inst_scalar_ty = inst_ty.scalarType(mod);
+ const inst_scalar_ty = inst_ty.scalarType(zcu);
- if (inst_scalar_ty.isInt(mod) and inst_scalar_ty.bitSize(mod) > 64)
+ if (inst_scalar_ty.isInt(zcu) and inst_scalar_ty.bitSize(zcu) > 64)
return try airBinBuiltinCall(f, inst, operation[1..], .none);
if (inst_scalar_ty.isRuntimeFloat())
return try airBinFloatOp(f, inst, operation);
@@ -4274,7 +4347,7 @@ fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: u8, operation: []cons
}
fn airSlice(f: *Function, inst: Air.Inst.Index) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;
@@ -4283,7 +4356,7 @@ fn airSlice(f: *Function, inst: Air.Inst.Index) !CValue {
try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
const inst_ty = f.typeOfIndex(inst);
- const ptr_ty = inst_ty.slicePtrFieldType(mod);
+ const ptr_ty = inst_ty.slicePtrFieldType(zcu);
const writer = f.object.writer();
const local = try f.allocLocal(inst, inst_ty);
@@ -4291,9 +4364,6 @@ fn airSlice(f: *Function, inst: Air.Inst.Index) !CValue {
const a = try Assignment.start(f, writer, ptr_ty);
try f.writeCValueMember(writer, local, .{ .identifier = "ptr" });
try a.assign(f, writer);
- try writer.writeByte('(');
- try f.renderType(writer, ptr_ty);
- try writer.writeByte(')');
try f.writeCValue(writer, ptr, .Other);
try a.end(f, writer);
}
@@ -4301,7 +4371,7 @@ fn airSlice(f: *Function, inst: Air.Inst.Index) !CValue {
const a = try Assignment.start(f, writer, Type.usize);
try f.writeCValueMember(writer, local, .{ .identifier = "len" });
try a.assign(f, writer);
- try f.writeCValue(writer, len, .Other);
+ try f.writeCValue(writer, len, .Initializer);
try a.end(f, writer);
}
return local;
@@ -4312,7 +4382,7 @@ fn airCall(
inst: Air.Inst.Index,
modifier: std.builtin.CallModifier,
) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
// Not even allowed to call panic in a naked function.
if (f.object.dg.is_naked_fn) return .none;
@@ -4334,7 +4404,7 @@ fn airCall(
}
resolved_arg.* = try f.resolveInst(arg);
if (arg_cty != try f.typeToIndex(arg_ty, .complete)) {
- const lowered_arg_ty = try lowerFnRetTy(arg_ty, mod);
+ const lowered_arg_ty = try lowerFnRetTy(arg_ty, zcu);
const array_local = try f.allocLocal(inst, lowered_arg_ty);
try writer.writeAll("memcpy(");
@@ -4357,20 +4427,19 @@ fn airCall(
}
const callee_ty = f.typeOf(pl_op.operand);
- const fn_ty = switch (callee_ty.zigTypeTag(mod)) {
+ const fn_info = zcu.typeToFunc(switch (callee_ty.zigTypeTag(zcu)) {
.Fn => callee_ty,
- .Pointer => callee_ty.childType(mod),
+ .Pointer => callee_ty.childType(zcu),
else => unreachable,
- };
-
- const ret_ty = fn_ty.fnReturnType(mod);
- const lowered_ret_ty = try lowerFnRetTy(ret_ty, mod);
+ }).?;
+ const ret_ty = Type.fromInterned(fn_info.return_type);
+ const lowered_ret_ty = try lowerFnRetTy(ret_ty, zcu);
const result_local = result: {
if (modifier == .always_tail) {
try writer.writeAll("zig_always_tail return ");
break :result .none;
- } else if (!lowered_ret_ty.hasRuntimeBitsIgnoreComptime(mod)) {
+ } else if (!lowered_ret_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
break :result .none;
} else if (f.liveness.isUnused(inst)) {
try writer.writeByte('(');
@@ -4388,8 +4457,8 @@ fn airCall(
callee: {
known: {
const fn_decl = fn_decl: {
- const callee_val = (try f.air.value(pl_op.operand, mod)) orelse break :known;
- break :fn_decl switch (mod.intern_pool.indexToKey(callee_val.ip_index)) {
+ const callee_val = (try f.air.value(pl_op.operand, zcu)) orelse break :known;
+ break :fn_decl switch (zcu.intern_pool.indexToKey(callee_val.toIntern())) {
.extern_func => |extern_func| extern_func.decl,
.func => |func| func.owner_decl,
.ptr => |ptr| switch (ptr.addr) {
@@ -4420,18 +4489,21 @@ fn airCall(
}
try writer.writeByte('(');
- var args_written: usize = 0;
+ var need_comma = false;
for (resolved_args) |resolved_arg| {
if (resolved_arg == .none) continue;
- if (args_written != 0) try writer.writeAll(", ");
+ if (need_comma) try writer.writeAll(", ");
+ need_comma = true;
try f.writeCValue(writer, resolved_arg, .FunctionArgument);
- if (resolved_arg == .new_local) try freeLocal(f, inst, resolved_arg.new_local, null);
- args_written += 1;
+ switch (resolved_arg) {
+ .new_local => |local| try freeLocal(f, inst, local, null),
+ else => {},
+ }
}
try writer.writeAll(");\n");
const result = result: {
- if (result_local == .none or !lowersToArray(ret_ty, mod))
+ if (result_local == .none or !lowersToArray(ret_ty, zcu))
break :result result_local;
const array_local = try f.allocLocal(inst, ret_ty);
@@ -4465,22 +4537,22 @@ fn airDbgStmt(f: *Function, inst: Air.Inst.Index) !CValue {
}
fn airDbgInlineBlock(f: *Function, inst: Air.Inst.Index) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = f.air.extraData(Air.DbgInlineBlock, ty_pl.payload);
- const owner_decl = mod.funcOwnerDeclPtr(extra.data.func);
+ const owner_decl = zcu.funcOwnerDeclPtr(extra.data.func);
const writer = f.object.writer();
try writer.writeAll("/* ");
- try owner_decl.renderFullyQualifiedName(mod, writer);
+ try owner_decl.renderFullyQualifiedName(zcu, writer);
try writer.writeAll(" */ ");
return lowerBlock(f, inst, @ptrCast(f.air.extra[extra.end..][0..extra.data.body_len]));
}
fn airDbgVar(f: *Function, inst: Air.Inst.Index) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
const name = f.air.nullTerminatedString(pl_op.payload);
- const operand_is_undef = if (try f.air.value(pl_op.operand, mod)) |v| v.isUndefDeep(mod) else false;
+ const operand_is_undef = if (try f.air.value(pl_op.operand, zcu)) |v| v.isUndefDeep(zcu) else false;
if (!operand_is_undef) _ = try f.resolveInst(pl_op.operand);
try reap(f, inst, &.{pl_op.operand});
@@ -4496,7 +4568,7 @@ fn airBlock(f: *Function, inst: Air.Inst.Index) !CValue {
}
fn lowerBlock(f: *Function, inst: Air.Inst.Index, body: []const Air.Inst.Index) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const liveness_block = f.liveness.getBlock(inst);
const block_id: usize = f.next_block_index;
@@ -4504,7 +4576,7 @@ fn lowerBlock(f: *Function, inst: Air.Inst.Index, body: []const Air.Inst.Index)
const writer = f.object.writer();
const inst_ty = f.typeOfIndex(inst);
- const result = if (inst_ty.hasRuntimeBitsIgnoreComptime(mod) and !f.liveness.isUnused(inst))
+ const result = if (inst_ty.hasRuntimeBitsIgnoreComptime(zcu) and !f.liveness.isUnused(inst))
try f.allocLocal(inst, inst_ty)
else
.none;
@@ -4526,7 +4598,7 @@ fn lowerBlock(f: *Function, inst: Air.Inst.Index, body: []const Air.Inst.Index)
try f.object.indent_writer.insertNewline();
// noreturn blocks have no `br` instructions reaching them, so we don't want a label
- if (!f.typeOfIndex(inst).isNoReturn(mod)) {
+ if (!f.typeOfIndex(inst).isNoReturn(zcu)) {
// label must be followed by an expression, include an empty one.
try writer.print("zig_block_{d}:;\n", .{block_id});
}
@@ -4543,11 +4615,11 @@ fn airTry(f: *Function, inst: Air.Inst.Index) !CValue {
}
fn airTryPtr(f: *Function, inst: Air.Inst.Index) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = f.air.extraData(Air.TryPtr, ty_pl.payload);
const body: []const Air.Inst.Index = @ptrCast(f.air.extra[extra.end..][0..extra.data.body_len]);
- const err_union_ty = f.typeOf(extra.data.ptr).childType(mod);
+ const err_union_ty = f.typeOf(extra.data.ptr).childType(zcu);
return lowerTry(f, inst, extra.data.ptr, body, err_union_ty, true);
}
@@ -4559,15 +4631,15 @@ fn lowerTry(
err_union_ty: Type,
is_ptr: bool,
) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const err_union = try f.resolveInst(operand);
const inst_ty = f.typeOfIndex(inst);
const liveness_condbr = f.liveness.getCondBr(inst);
const writer = f.object.writer();
- const payload_ty = err_union_ty.errorUnionPayload(mod);
- const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(mod);
+ const payload_ty = err_union_ty.errorUnionPayload(zcu);
+ const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(zcu);
- if (!err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) {
+ if (!err_union_ty.errorUnionSet(zcu).errorSetIsEmpty(zcu)) {
try writer.writeAll("if (");
if (!payload_has_bits) {
if (is_ptr)
@@ -4661,7 +4733,7 @@ const LocalResult = struct {
need_free: bool,
fn move(lr: LocalResult, f: *Function, inst: Air.Inst.Index, dest_ty: Type) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
if (lr.need_free) {
// Move the freshly allocated local to be owned by this instruction,
@@ -4673,7 +4745,7 @@ const LocalResult = struct {
try lr.free(f);
const writer = f.object.writer();
try f.writeCValue(writer, local, .Other);
- if (dest_ty.isAbiInt(mod)) {
+ if (dest_ty.isAbiInt(zcu)) {
try writer.writeAll(" = ");
} else {
try writer.writeAll(" = (");
@@ -4693,13 +4765,13 @@ const LocalResult = struct {
};
fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !LocalResult {
- const mod = f.object.dg.module;
- const target = mod.getTarget();
+ const zcu = f.object.dg.zcu;
+ const target = &f.object.dg.mod.resolved_target.result;
const writer = f.object.writer();
- if (operand_ty.isAbiInt(mod) and dest_ty.isAbiInt(mod)) {
- const src_info = dest_ty.intInfo(mod);
- const dest_info = operand_ty.intInfo(mod);
+ if (operand_ty.isAbiInt(zcu) and dest_ty.isAbiInt(zcu)) {
+ const src_info = dest_ty.intInfo(zcu);
+ const dest_info = operand_ty.intInfo(zcu);
if (src_info.signedness == dest_info.signedness and
src_info.bits == dest_info.bits)
{
@@ -4710,7 +4782,7 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !Loca
}
}
- if (dest_ty.isPtrAtRuntime(mod) and operand_ty.isPtrAtRuntime(mod)) {
+ if (dest_ty.isPtrAtRuntime(zcu) and operand_ty.isPtrAtRuntime(zcu)) {
const local = try f.allocLocal(null, dest_ty);
try f.writeCValue(writer, local, .Other);
try writer.writeAll(" = (");
@@ -4727,7 +4799,7 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !Loca
const operand_lval = if (operand == .constant) blk: {
const operand_local = try f.allocLocal(null, operand_ty);
try f.writeCValue(writer, operand_local, .Other);
- if (operand_ty.isAbiInt(mod)) {
+ if (operand_ty.isAbiInt(zcu)) {
try writer.writeAll(" = ");
} else {
try writer.writeAll(" = (");
@@ -4747,14 +4819,14 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !Loca
try writer.writeAll(", sizeof(");
try f.renderType(
writer,
- if (dest_ty.abiSize(mod) <= operand_ty.abiSize(mod)) dest_ty else operand_ty,
+ if (dest_ty.abiSize(zcu) <= operand_ty.abiSize(zcu)) dest_ty else operand_ty,
);
try writer.writeAll("));\n");
// Ensure padding bits have the expected value.
- if (dest_ty.isAbiInt(mod)) {
+ if (dest_ty.isAbiInt(zcu)) {
const dest_cty = try f.typeToCType(dest_ty, .complete);
- const dest_info = dest_ty.intInfo(mod);
+ const dest_info = dest_ty.intInfo(zcu);
var bits: u16 = dest_info.bits;
var wrap_cty: ?CType = null;
var need_bitcasts = false;
@@ -4779,7 +4851,7 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !Loca
try writer.writeByte('(');
}
try writer.writeAll("zig_wrap_");
- const info_ty = try mod.intType(dest_info.signedness, bits);
+ const info_ty = try zcu.intType(dest_info.signedness, bits);
if (wrap_cty) |cty|
try f.object.dg.renderCTypeForBuiltinFnName(writer, cty)
else
@@ -4912,7 +4984,7 @@ fn airCondBr(f: *Function, inst: Air.Inst.Index) !CValue {
}
fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
const condition = try f.resolveInst(pl_op.operand);
try reap(f, inst, &.{pl_op.operand});
@@ -4921,11 +4993,11 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue {
const writer = f.object.writer();
try writer.writeAll("switch (");
- if (condition_ty.zigTypeTag(mod) == .Bool) {
+ if (condition_ty.zigTypeTag(zcu) == .Bool) {
try writer.writeByte('(');
try f.renderType(writer, Type.u1);
try writer.writeByte(')');
- } else if (condition_ty.isPtrAtRuntime(mod)) {
+ } else if (condition_ty.isPtrAtRuntime(zcu)) {
try writer.writeByte('(');
try f.renderType(writer, Type.usize);
try writer.writeByte(')');
@@ -4952,12 +5024,12 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue {
for (items) |item| {
try f.object.indent_writer.insertNewline();
try writer.writeAll("case ");
- if (condition_ty.isPtrAtRuntime(mod)) {
+ if (condition_ty.isPtrAtRuntime(zcu)) {
try writer.writeByte('(');
try f.renderType(writer, Type.usize);
try writer.writeByte(')');
}
- try f.object.dg.renderValue(writer, condition_ty, (try f.air.value(item, mod)).?, .Other);
+ try f.object.dg.renderValue(writer, (try f.air.value(item, zcu)).?, .Other);
try writer.writeByte(':');
}
try writer.writeByte(' ');
@@ -4994,13 +5066,13 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue {
}
fn asmInputNeedsLocal(f: *Function, constraint: []const u8, value: CValue) bool {
- const target = f.object.dg.module.getTarget();
+ const target = &f.object.dg.mod.resolved_target.result;
return switch (constraint[0]) {
'{' => true,
'i', 'r' => false,
'I' => !target.cpu.arch.isArmOrThumb(),
else => switch (value) {
- .constant => |val| switch (f.object.dg.module.intern_pool.indexToKey(val)) {
+ .constant => |val| switch (f.object.dg.zcu.intern_pool.indexToKey(val.toIntern())) {
.ptr => |ptr| switch (ptr.addr) {
.decl => false,
else => true,
@@ -5013,7 +5085,7 @@ fn asmInputNeedsLocal(f: *Function, constraint: []const u8, value: CValue) bool
}
fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = f.air.extraData(Air.Asm, ty_pl.payload);
const is_volatile = @as(u1, @truncate(extra.data.flags >> 31)) != 0;
@@ -5028,7 +5100,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
const result = result: {
const writer = f.object.writer();
const inst_ty = f.typeOfIndex(inst);
- const local = if (inst_ty.hasRuntimeBitsIgnoreComptime(mod)) local: {
+ const local = if (inst_ty.hasRuntimeBitsIgnoreComptime(zcu)) local: {
const local = try f.allocLocal(inst, inst_ty);
if (f.wantSafety()) {
try f.writeCValue(writer, local, .Other);
@@ -5057,7 +5129,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
const is_reg = constraint[1] == '{';
if (is_reg) {
- const output_ty = if (output == .none) inst_ty else f.typeOf(output).childType(mod);
+ const output_ty = if (output == .none) inst_ty else f.typeOf(output).childType(zcu);
try writer.writeAll("register ");
const alignment: Alignment = .none;
const local_value = try f.allocLocalValue(output_ty, alignment);
@@ -5275,7 +5347,7 @@ fn airIsNull(
operator: []const u8,
is_ptr: bool,
) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const writer = f.object.writer();
@@ -5292,22 +5364,22 @@ fn airIsNull(
}
const operand_ty = f.typeOf(un_op);
- const optional_ty = if (is_ptr) operand_ty.childType(mod) else operand_ty;
- const payload_ty = optional_ty.optionalChild(mod);
- const err_int_ty = try mod.errorIntType();
+ const optional_ty = if (is_ptr) operand_ty.childType(zcu) else operand_ty;
+ const payload_ty = optional_ty.optionalChild(zcu);
+ const err_int_ty = try zcu.errorIntType();
- const rhs = if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod))
+ const rhs = if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu))
Value.true
- else if (optional_ty.isPtrLikeOptional(mod))
+ else if (optional_ty.isPtrLikeOptional(zcu))
// operand is a regular pointer, test `operand !=/== NULL`
- try mod.getCoerced(Value.null, optional_ty)
- else if (payload_ty.zigTypeTag(mod) == .ErrorSet)
- try mod.intValue(err_int_ty, 0)
- else if (payload_ty.isSlice(mod) and optional_ty.optionalReprIsPayload(mod)) rhs: {
+ try zcu.getCoerced(Value.null, optional_ty)
+ else if (payload_ty.zigTypeTag(zcu) == .ErrorSet)
+ try zcu.intValue(err_int_ty, 0)
+ else if (payload_ty.isSlice(zcu) and optional_ty.optionalReprIsPayload(zcu)) rhs: {
try writer.writeAll(".ptr");
- const slice_ptr_ty = payload_ty.slicePtrFieldType(mod);
- const opt_slice_ptr_ty = try mod.optionalType(slice_ptr_ty.toIntern());
- break :rhs try mod.nullValue(opt_slice_ptr_ty);
+ const slice_ptr_ty = payload_ty.slicePtrFieldType(zcu);
+ const opt_slice_ptr_ty = try zcu.optionalType(slice_ptr_ty.toIntern());
+ break :rhs try zcu.nullValue(opt_slice_ptr_ty);
} else rhs: {
try writer.writeAll(".is_null");
break :rhs Value.true;
@@ -5315,22 +5387,22 @@ fn airIsNull(
try writer.writeByte(' ');
try writer.writeAll(operator);
try writer.writeByte(' ');
- try f.object.dg.renderValue(writer, rhs.typeOf(mod), rhs, .Other);
+ try f.object.dg.renderValue(writer, rhs, .Other);
try writer.writeAll(";\n");
return local;
}
fn airOptionalPayload(f: *Function, inst: Air.Inst.Index) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const operand = try f.resolveInst(ty_op.operand);
try reap(f, inst, &.{ty_op.operand});
const opt_ty = f.typeOf(ty_op.operand);
- const payload_ty = opt_ty.optionalChild(mod);
+ const payload_ty = opt_ty.optionalChild(zcu);
- if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
+ if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
return .none;
}
@@ -5338,7 +5410,7 @@ fn airOptionalPayload(f: *Function, inst: Air.Inst.Index) !CValue {
const writer = f.object.writer();
const local = try f.allocLocal(inst, inst_ty);
- if (opt_ty.optionalReprIsPayload(mod)) {
+ if (opt_ty.optionalReprIsPayload(zcu)) {
try f.writeCValue(writer, local, .Other);
try writer.writeAll(" = ");
try f.writeCValue(writer, operand, .Other);
@@ -5355,24 +5427,24 @@ fn airOptionalPayload(f: *Function, inst: Air.Inst.Index) !CValue {
}
fn airOptionalPayloadPtr(f: *Function, inst: Air.Inst.Index) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const writer = f.object.writer();
const operand = try f.resolveInst(ty_op.operand);
try reap(f, inst, &.{ty_op.operand});
const ptr_ty = f.typeOf(ty_op.operand);
- const opt_ty = ptr_ty.childType(mod);
+ const opt_ty = ptr_ty.childType(zcu);
const inst_ty = f.typeOfIndex(inst);
- if (!inst_ty.childType(mod).hasRuntimeBitsIgnoreComptime(mod)) {
+ if (!inst_ty.childType(zcu).hasRuntimeBitsIgnoreComptime(zcu)) {
return .{ .undef = inst_ty };
}
const local = try f.allocLocal(inst, inst_ty);
try f.writeCValue(writer, local, .Other);
- if (opt_ty.optionalReprIsPayload(mod)) {
+ if (opt_ty.optionalReprIsPayload(zcu)) {
// the operand is just a regular pointer, no need to do anything special.
// *?*T -> **T and ?*T -> *T are **T -> **T and *T -> *T in C
try writer.writeAll(" = ");
@@ -5386,18 +5458,18 @@ fn airOptionalPayloadPtr(f: *Function, inst: Air.Inst.Index) !CValue {
}
fn airOptionalPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const writer = f.object.writer();
const operand = try f.resolveInst(ty_op.operand);
try reap(f, inst, &.{ty_op.operand});
const operand_ty = f.typeOf(ty_op.operand);
- const opt_ty = operand_ty.childType(mod);
+ const opt_ty = operand_ty.childType(zcu);
const inst_ty = f.typeOfIndex(inst);
- if (opt_ty.optionalReprIsPayload(mod)) {
+ if (opt_ty.optionalReprIsPayload(zcu)) {
if (f.liveness.isUnused(inst)) {
return .none;
}
@@ -5412,7 +5484,7 @@ fn airOptionalPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
} else {
try f.writeCValueDeref(writer, operand);
try writer.writeAll(".is_null = ");
- try f.object.dg.renderValue(writer, Type.bool, Value.false, .Initializer);
+ try f.object.dg.renderValue(writer, Value.false, .Initializer);
try writer.writeAll(";\n");
if (f.liveness.isUnused(inst)) {
@@ -5432,50 +5504,50 @@ fn fieldLocation(
container_ptr_ty: Type,
field_ptr_ty: Type,
field_index: u32,
- mod: *Module,
+ zcu: *Zcu,
) union(enum) {
begin: void,
field: CValue,
byte_offset: u32,
end: void,
} {
- const ip = &mod.intern_pool;
- const container_ty = container_ptr_ty.childType(mod);
- return switch (container_ty.zigTypeTag(mod)) {
+ const ip = &zcu.intern_pool;
+ const container_ty = container_ptr_ty.childType(zcu);
+ return switch (container_ty.zigTypeTag(zcu)) {
.Struct => blk: {
- if (mod.typeToPackedStruct(container_ty)) |struct_type| {
- if (field_ptr_ty.ptrInfo(mod).packed_offset.host_size == 0)
- break :blk .{ .byte_offset = @divExact(mod.structPackedFieldBitOffset(struct_type, field_index) + container_ptr_ty.ptrInfo(mod).packed_offset.bit_offset, 8) }
+ if (zcu.typeToPackedStruct(container_ty)) |struct_type| {
+ if (field_ptr_ty.ptrInfo(zcu).packed_offset.host_size == 0)
+ break :blk .{ .byte_offset = @divExact(zcu.structPackedFieldBitOffset(struct_type, field_index) + container_ptr_ty.ptrInfo(zcu).packed_offset.bit_offset, 8) }
else
break :blk .begin;
}
- for (field_index..container_ty.structFieldCount(mod)) |next_field_index_usize| {
+ for (field_index..container_ty.structFieldCount(zcu)) |next_field_index_usize| {
const next_field_index: u32 = @intCast(next_field_index_usize);
- if (container_ty.structFieldIsComptime(next_field_index, mod)) continue;
- const field_ty = container_ty.structFieldType(next_field_index, mod);
- if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
+ if (container_ty.structFieldIsComptime(next_field_index, zcu)) continue;
+ const field_ty = container_ty.structFieldType(next_field_index, zcu);
+ if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
- break :blk .{ .field = if (container_ty.isSimpleTuple(mod))
+ break :blk .{ .field = if (container_ty.isSimpleTuple(zcu))
.{ .field = next_field_index }
else
- .{ .identifier = ip.stringToSlice(container_ty.legacyStructFieldName(next_field_index, mod)) } };
+ .{ .identifier = ip.stringToSlice(container_ty.legacyStructFieldName(next_field_index, zcu)) } };
}
- break :blk if (container_ty.hasRuntimeBitsIgnoreComptime(mod)) .end else .begin;
+ break :blk if (container_ty.hasRuntimeBitsIgnoreComptime(zcu)) .end else .begin;
},
.Union => {
- const union_obj = mod.typeToUnion(container_ty).?;
+ const union_obj = zcu.typeToUnion(container_ty).?;
return switch (union_obj.getLayout(ip)) {
.auto, .@"extern" => {
const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);
- if (!field_ty.hasRuntimeBitsIgnoreComptime(mod))
- return if (container_ty.unionTagTypeSafety(mod) != null and
- !container_ty.unionHasAllZeroBitFieldTypes(mod))
+ if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu))
+ return if (container_ty.unionTagTypeSafety(zcu) != null and
+ !container_ty.unionHasAllZeroBitFieldTypes(zcu))
.{ .field = .{ .identifier = "payload" } }
else
.begin;
const field_name = union_obj.loadTagType(ip).names.get(ip)[field_index];
- return .{ .field = if (container_ty.unionTagTypeSafety(mod)) |_|
+ return .{ .field = if (container_ty.unionTagTypeSafety(zcu)) |_|
.{ .payload_identifier = ip.stringToSlice(field_name) }
else
.{ .identifier = ip.stringToSlice(field_name) } };
@@ -5483,7 +5555,7 @@ fn fieldLocation(
.@"packed" => .begin,
};
},
- .Pointer => switch (container_ty.ptrSize(mod)) {
+ .Pointer => switch (container_ty.ptrSize(zcu)) {
.Slice => switch (field_index) {
0 => .{ .field = .{ .identifier = "ptr" } },
1 => .{ .field = .{ .identifier = "len" } },
@@ -5515,12 +5587,12 @@ fn airStructFieldPtrIndex(f: *Function, inst: Air.Inst.Index, index: u8) !CValue
}
fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = f.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;
const container_ptr_ty = f.typeOfIndex(inst);
- const container_ty = container_ptr_ty.childType(mod);
+ const container_ty = container_ptr_ty.childType(zcu);
const field_ptr_ty = f.typeOf(extra.field_ptr);
const field_ptr_val = try f.resolveInst(extra.field_ptr);
@@ -5533,10 +5605,10 @@ fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue {
try f.renderType(writer, container_ptr_ty);
try writer.writeByte(')');
- switch (fieldLocation(container_ptr_ty, field_ptr_ty, extra.field_index, mod)) {
+ switch (fieldLocation(container_ptr_ty, field_ptr_ty, extra.field_index, zcu)) {
.begin => try f.writeCValue(writer, field_ptr_val, .Initializer),
.field => |field| {
- const u8_ptr_ty = try mod.adjustPtrTypeChild(field_ptr_ty, Type.u8);
+ const u8_ptr_ty = try zcu.adjustPtrTypeChild(field_ptr_ty, Type.u8);
try writer.writeAll("((");
try f.renderType(writer, u8_ptr_ty);
@@ -5549,19 +5621,19 @@ fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue {
try writer.writeAll("))");
},
.byte_offset => |byte_offset| {
- const u8_ptr_ty = try mod.adjustPtrTypeChild(field_ptr_ty, Type.u8);
-
- const byte_offset_val = try mod.intValue(Type.usize, byte_offset);
+ const u8_ptr_ty = try zcu.adjustPtrTypeChild(field_ptr_ty, Type.u8);
try writer.writeAll("((");
try f.renderType(writer, u8_ptr_ty);
try writer.writeByte(')');
try f.writeCValue(writer, field_ptr_val, .Other);
- try writer.print(" - {})", .{try f.fmtIntLiteral(Type.usize, byte_offset_val)});
+ try writer.print(" - {})", .{
+ try f.fmtIntLiteral(try zcu.intValue(Type.usize, byte_offset)),
+ });
},
.end => {
try f.writeCValue(writer, field_ptr_val, .Other);
- try writer.print(" - {}", .{try f.fmtIntLiteral(Type.usize, try mod.intValue(Type.usize, 1))});
+ try writer.print(" - {}", .{try f.fmtIntLiteral(try zcu.intValue(Type.usize, 1))});
},
}
@@ -5576,8 +5648,8 @@ fn fieldPtr(
container_ptr_val: CValue,
field_index: u32,
) !CValue {
- const mod = f.object.dg.module;
- const container_ty = container_ptr_ty.childType(mod);
+ const zcu = f.object.dg.zcu;
+ const container_ty = container_ptr_ty.childType(zcu);
const field_ptr_ty = f.typeOfIndex(inst);
// Ensure complete type definition is visible before accessing fields.
@@ -5590,27 +5662,27 @@ fn fieldPtr(
try f.renderType(writer, field_ptr_ty);
try writer.writeByte(')');
- switch (fieldLocation(container_ptr_ty, field_ptr_ty, field_index, mod)) {
+ switch (fieldLocation(container_ptr_ty, field_ptr_ty, field_index, zcu)) {
.begin => try f.writeCValue(writer, container_ptr_val, .Initializer),
.field => |field| {
try writer.writeByte('&');
try f.writeCValueDerefMember(writer, container_ptr_val, field);
},
.byte_offset => |byte_offset| {
- const u8_ptr_ty = try mod.adjustPtrTypeChild(field_ptr_ty, Type.u8);
-
- const byte_offset_val = try mod.intValue(Type.usize, byte_offset);
+ const u8_ptr_ty = try zcu.adjustPtrTypeChild(field_ptr_ty, Type.u8);
try writer.writeAll("((");
try f.renderType(writer, u8_ptr_ty);
try writer.writeByte(')');
try f.writeCValue(writer, container_ptr_val, .Other);
- try writer.print(" + {})", .{try f.fmtIntLiteral(Type.usize, byte_offset_val)});
+ try writer.print(" + {})", .{
+ try f.fmtIntLiteral(try zcu.intValue(Type.usize, byte_offset)),
+ });
},
.end => {
try writer.writeByte('(');
try f.writeCValue(writer, container_ptr_val, .Other);
- try writer.print(" + {})", .{try f.fmtIntLiteral(Type.usize, try mod.intValue(Type.usize, 1))});
+ try writer.print(" + {})", .{try f.fmtIntLiteral(try zcu.intValue(Type.usize, 1))});
},
}
@@ -5619,13 +5691,13 @@ fn fieldPtr(
}
fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
- const mod = f.object.dg.module;
- const ip = &mod.intern_pool;
+ const zcu = f.object.dg.zcu;
+ const ip = &zcu.intern_pool;
const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = f.air.extraData(Air.StructField, ty_pl.payload).data;
const inst_ty = f.typeOfIndex(inst);
- if (!inst_ty.hasRuntimeBitsIgnoreComptime(mod)) {
+ if (!inst_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
try reap(f, inst, &.{extra.struct_operand});
return .none;
}
@@ -5638,26 +5710,25 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
// Ensure complete type definition is visible before accessing fields.
_ = try f.typeToIndex(struct_ty, .complete);
- const field_name: CValue = switch (mod.intern_pool.indexToKey(struct_ty.ip_index)) {
- .struct_type => switch (struct_ty.containerLayout(mod)) {
- .auto, .@"extern" => if (struct_ty.isSimpleTuple(mod))
+ const field_name: CValue = switch (zcu.intern_pool.indexToKey(struct_ty.toIntern())) {
+ .struct_type => switch (struct_ty.containerLayout(zcu)) {
+ .auto, .@"extern" => if (struct_ty.isSimpleTuple(zcu))
.{ .field = extra.field_index }
else
- .{ .identifier = ip.stringToSlice(struct_ty.legacyStructFieldName(extra.field_index, mod)) },
+ .{ .identifier = ip.stringToSlice(struct_ty.legacyStructFieldName(extra.field_index, zcu)) },
.@"packed" => {
- const struct_type = mod.typeToStruct(struct_ty).?;
- const int_info = struct_ty.intInfo(mod);
+ const struct_type = zcu.typeToStruct(struct_ty).?;
+ const int_info = struct_ty.intInfo(zcu);
- const bit_offset_ty = try mod.intType(.unsigned, Type.smallestUnsignedBits(int_info.bits - 1));
+ const bit_offset_ty = try zcu.intType(.unsigned, Type.smallestUnsignedBits(int_info.bits - 1));
- const bit_offset = mod.structPackedFieldBitOffset(struct_type, extra.field_index);
- const bit_offset_val = try mod.intValue(bit_offset_ty, bit_offset);
+ const bit_offset = zcu.structPackedFieldBitOffset(struct_type, extra.field_index);
- const field_int_signedness = if (inst_ty.isAbiInt(mod))
- inst_ty.intInfo(mod).signedness
+ const field_int_signedness = if (inst_ty.isAbiInt(zcu))
+ inst_ty.intInfo(zcu).signedness
else
.unsigned;
- const field_int_ty = try mod.intType(field_int_signedness, @as(u16, @intCast(inst_ty.bitSize(mod))));
+ const field_int_ty = try zcu.intType(field_int_signedness, @as(u16, @intCast(inst_ty.bitSize(zcu))));
const temp_local = try f.allocLocal(inst, field_int_ty);
try f.writeCValue(writer, temp_local, .Other);
@@ -5668,7 +5739,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
try writer.writeByte(')');
const cant_cast = int_info.bits > 64;
if (cant_cast) {
- if (field_int_ty.bitSize(mod) > 64) return f.fail("TODO: C backend: implement casting between types > 64 bits", .{});
+ if (field_int_ty.bitSize(zcu) > 64) return f.fail("TODO: C backend: implement casting between types > 64 bits", .{});
try writer.writeAll("zig_lo_");
try f.object.dg.renderTypeForBuiltinFnName(writer, struct_ty);
try writer.writeByte('(');
@@ -5681,13 +5752,13 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
try f.writeCValue(writer, struct_byval, .Other);
if (bit_offset > 0) {
try writer.writeAll(", ");
- try f.object.dg.renderValue(writer, bit_offset_ty, bit_offset_val, .FunctionArgument);
+ try f.object.dg.renderValue(writer, try zcu.intValue(bit_offset_ty, bit_offset), .FunctionArgument);
try writer.writeByte(')');
}
if (cant_cast) try writer.writeByte(')');
try f.object.dg.renderBuiltinInfo(writer, field_int_ty, .bits);
try writer.writeAll(");\n");
- if (inst_ty.eql(field_int_ty, f.object.dg.module)) return temp_local;
+ if (inst_ty.eql(field_int_ty, f.object.dg.zcu)) return temp_local;
const local = try f.allocLocal(inst, inst_ty);
try writer.writeAll("memcpy(");
@@ -5705,7 +5776,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
.anon_struct_type => |anon_struct_type| if (anon_struct_type.names.len == 0)
.{ .field = extra.field_index }
else
- .{ .identifier = ip.stringToSlice(struct_ty.legacyStructFieldName(extra.field_index, mod)) },
+ .{ .identifier = ip.stringToSlice(struct_ty.legacyStructFieldName(extra.field_index, zcu)) },
.union_type => field_name: {
const union_obj = ip.loadUnionType(struct_ty.toIntern());
@@ -5757,7 +5828,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
/// *(E!T) -> E
/// Note that the result is never a pointer.
fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const inst_ty = f.typeOfIndex(inst);
@@ -5765,13 +5836,13 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
const operand_ty = f.typeOf(ty_op.operand);
try reap(f, inst, &.{ty_op.operand});
- const operand_is_ptr = operand_ty.zigTypeTag(mod) == .Pointer;
- const error_union_ty = if (operand_is_ptr) operand_ty.childType(mod) else operand_ty;
- const error_ty = error_union_ty.errorUnionSet(mod);
- const payload_ty = error_union_ty.errorUnionPayload(mod);
+ const operand_is_ptr = operand_ty.zigTypeTag(zcu) == .Pointer;
+ const error_union_ty = if (operand_is_ptr) operand_ty.childType(zcu) else operand_ty;
+ const error_ty = error_union_ty.errorUnionSet(zcu);
+ const payload_ty = error_union_ty.errorUnionPayload(zcu);
const local = try f.allocLocal(inst, inst_ty);
- if (!payload_ty.hasRuntimeBits(mod) and operand == .local and operand.local == local.new_local) {
+ if (!payload_ty.hasRuntimeBits(zcu) and operand == .local and operand.local == local.new_local) {
// The store will be 'x = x'; elide it.
return local;
}
@@ -5780,35 +5851,32 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
try f.writeCValue(writer, local, .Other);
try writer.writeAll(" = ");
- if (!payload_ty.hasRuntimeBits(mod)) {
- try f.writeCValue(writer, operand, .Other);
- } else {
- if (!error_ty.errorSetIsEmpty(mod))
- if (operand_is_ptr)
- try f.writeCValueDerefMember(writer, operand, .{ .identifier = "error" })
- else
- try f.writeCValueMember(writer, operand, .{ .identifier = "error" })
- else {
- const err_int_ty = try mod.errorIntType();
- try f.object.dg.renderValue(writer, err_int_ty, try mod.intValue(err_int_ty, 0), .Initializer);
- }
- }
+ if (!payload_ty.hasRuntimeBits(zcu))
+ try f.writeCValue(writer, operand, .Other)
+ else if (error_ty.errorSetIsEmpty(zcu))
+ try writer.print("{}", .{
+ try f.fmtIntLiteral(try zcu.intValue(try zcu.errorIntType(), 0)),
+ })
+ else if (operand_is_ptr)
+ try f.writeCValueDerefMember(writer, operand, .{ .identifier = "error" })
+ else
+ try f.writeCValueMember(writer, operand, .{ .identifier = "error" });
try writer.writeAll(";\n");
return local;
}
fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const inst_ty = f.typeOfIndex(inst);
const operand = try f.resolveInst(ty_op.operand);
try reap(f, inst, &.{ty_op.operand});
const operand_ty = f.typeOf(ty_op.operand);
- const error_union_ty = if (is_ptr) operand_ty.childType(mod) else operand_ty;
+ const error_union_ty = if (is_ptr) operand_ty.childType(zcu) else operand_ty;
const writer = f.object.writer();
- if (!error_union_ty.errorUnionPayload(mod).hasRuntimeBits(mod)) {
+ if (!error_union_ty.errorUnionPayload(zcu).hasRuntimeBits(zcu)) {
if (!is_ptr) return .none;
const local = try f.allocLocal(inst, inst_ty);
@@ -5834,11 +5902,11 @@ fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValu
}
fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const inst_ty = f.typeOfIndex(inst);
- const repr_is_payload = inst_ty.optionalReprIsPayload(mod);
+ const repr_is_payload = inst_ty.optionalReprIsPayload(zcu);
const payload_ty = f.typeOf(ty_op.operand);
const payload = try f.resolveInst(ty_op.operand);
try reap(f, inst, &.{ty_op.operand});
@@ -5859,20 +5927,20 @@ fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue {
const a = try Assignment.start(f, writer, Type.bool);
try f.writeCValueMember(writer, local, .{ .identifier = "is_null" });
try a.assign(f, writer);
- try f.object.dg.renderValue(writer, Type.bool, Value.false, .Other);
+ try f.object.dg.renderValue(writer, Value.false, .Other);
try a.end(f, writer);
}
return local;
}
fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const inst_ty = f.typeOfIndex(inst);
- const payload_ty = inst_ty.errorUnionPayload(mod);
- const repr_is_err = !payload_ty.hasRuntimeBitsIgnoreComptime(mod);
- const err_ty = inst_ty.errorUnionSet(mod);
+ const payload_ty = inst_ty.errorUnionPayload(zcu);
+ const repr_is_err = !payload_ty.hasRuntimeBitsIgnoreComptime(zcu);
+ const err_ty = inst_ty.errorUnionSet(zcu);
const err = try f.resolveInst(ty_op.operand);
try reap(f, inst, &.{ty_op.operand});
@@ -5888,7 +5956,7 @@ fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
const a = try Assignment.start(f, writer, payload_ty);
try f.writeCValueMember(writer, local, .{ .identifier = "payload" });
try a.assign(f, writer);
- try f.object.dg.renderValue(writer, payload_ty, Value.undef, .Other);
+ try f.object.dg.renderUndefValue(writer, payload_ty, .Other);
try a.end(f, writer);
}
{
@@ -5905,29 +5973,25 @@ fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
}
fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const writer = f.object.writer();
const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const operand = try f.resolveInst(ty_op.operand);
- const error_union_ty = f.typeOf(ty_op.operand).childType(mod);
+ const error_union_ty = f.typeOf(ty_op.operand).childType(zcu);
- const payload_ty = error_union_ty.errorUnionPayload(mod);
- const err_int_ty = try mod.errorIntType();
+ const payload_ty = error_union_ty.errorUnionPayload(zcu);
+ const err_int_ty = try zcu.errorIntType();
+ const no_err = try zcu.intValue(err_int_ty, 0);
// First, set the non-error value.
- if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
+ if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
try f.writeCValueDeref(writer, operand);
- try writer.writeAll(" = ");
- try f.object.dg.renderValue(writer, err_int_ty, try mod.intValue(err_int_ty, 0), .Other);
- try writer.writeAll(";\n ");
-
+ try writer.print(" = {};\n", .{try f.fmtIntLiteral(no_err)});
return operand;
}
try reap(f, inst, &.{ty_op.operand});
try f.writeCValueDeref(writer, operand);
- try writer.writeAll(".error = ");
- try f.object.dg.renderValue(writer, err_int_ty, try mod.intValue(err_int_ty, 0), .Other);
- try writer.writeAll(";\n");
+ try writer.print(".error = {};\n", .{try f.fmtIntLiteral(no_err)});
// Then return the payload pointer (only if it is used)
if (f.liveness.isUnused(inst)) return .none;
@@ -5956,14 +6020,14 @@ fn airSaveErrReturnTraceIndex(f: *Function, inst: Air.Inst.Index) !CValue {
}
fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const inst_ty = f.typeOfIndex(inst);
- const payload_ty = inst_ty.errorUnionPayload(mod);
+ const payload_ty = inst_ty.errorUnionPayload(zcu);
const payload = try f.resolveInst(ty_op.operand);
- const repr_is_err = !payload_ty.hasRuntimeBitsIgnoreComptime(mod);
- const err_ty = inst_ty.errorUnionSet(mod);
+ const repr_is_err = !payload_ty.hasRuntimeBitsIgnoreComptime(zcu);
+ const err_ty = inst_ty.errorUnionSet(zcu);
try reap(f, inst, &.{ty_op.operand});
const writer = f.object.writer();
@@ -5982,15 +6046,14 @@ fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue {
else
try f.writeCValueMember(writer, local, .{ .identifier = "error" });
try a.assign(f, writer);
- const err_int_ty = try mod.errorIntType();
- try f.object.dg.renderValue(writer, err_int_ty, try mod.intValue(err_int_ty, 0), .Other);
+ try f.object.dg.renderValue(writer, try zcu.intValue(try zcu.errorIntType(), 0), .Other);
try a.end(f, writer);
}
return local;
}
fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const u8) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const writer = f.object.writer();
@@ -5998,16 +6061,16 @@ fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const
try reap(f, inst, &.{un_op});
const operand_ty = f.typeOf(un_op);
const local = try f.allocLocal(inst, Type.bool);
- const err_union_ty = if (is_ptr) operand_ty.childType(mod) else operand_ty;
- const payload_ty = err_union_ty.errorUnionPayload(mod);
- const error_ty = err_union_ty.errorUnionSet(mod);
+ const err_union_ty = if (is_ptr) operand_ty.childType(zcu) else operand_ty;
+ const payload_ty = err_union_ty.errorUnionPayload(zcu);
+ const error_ty = err_union_ty.errorUnionSet(zcu);
+ const a = try Assignment.start(f, writer, Type.bool);
try f.writeCValue(writer, local, .Other);
- try writer.writeAll(" = ");
-
- const err_int_ty = try mod.errorIntType();
- if (!error_ty.errorSetIsEmpty(mod))
- if (payload_ty.hasRuntimeBits(mod))
+ try a.assign(f, writer);
+ const err_int_ty = try zcu.errorIntType();
+ if (!error_ty.errorSetIsEmpty(zcu))
+ if (payload_ty.hasRuntimeBits(zcu))
if (is_ptr)
try f.writeCValueDerefMember(writer, operand, .{ .identifier = "error" })
else
@@ -6015,63 +6078,84 @@ fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const
else
try f.writeCValue(writer, operand, .Other)
else
- try f.object.dg.renderValue(writer, err_int_ty, try mod.intValue(err_int_ty, 0), .Other);
+ try f.object.dg.renderValue(writer, try zcu.intValue(err_int_ty, 0), .Other);
try writer.writeByte(' ');
try writer.writeAll(operator);
try writer.writeByte(' ');
- try f.object.dg.renderValue(writer, err_int_ty, try mod.intValue(err_int_ty, 0), .Other);
- try writer.writeAll(";\n");
+ try f.object.dg.renderValue(writer, try zcu.intValue(err_int_ty, 0), .Other);
+ try a.end(f, writer);
return local;
}
fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const operand = try f.resolveInst(ty_op.operand);
try reap(f, inst, &.{ty_op.operand});
const inst_ty = f.typeOfIndex(inst);
+ const ptr_ty = inst_ty.slicePtrFieldType(zcu);
const writer = f.object.writer();
const local = try f.allocLocal(inst, inst_ty);
- const array_ty = f.typeOf(ty_op.operand).childType(mod);
-
- try f.writeCValueMember(writer, local, .{ .identifier = "ptr" });
- try writer.writeAll(" = ");
- // Unfortunately, C does not support any equivalent to
- // &(*(void *)p)[0], although LLVM does via GetElementPtr
- if (operand == .undef) {
- try f.writeCValue(writer, .{ .undef = inst_ty.slicePtrFieldType(mod) }, .Initializer);
- } else if (array_ty.hasRuntimeBitsIgnoreComptime(mod)) {
- try writer.writeAll("&(");
- try f.writeCValueDeref(writer, operand);
- try writer.print(")[{}]", .{try f.fmtIntLiteral(Type.usize, try mod.intValue(Type.usize, 0))});
- } else try f.writeCValue(writer, operand, .Initializer);
- try writer.writeAll("; ");
+ const operand_ty = f.typeOf(ty_op.operand);
+ const array_ty = operand_ty.childType(zcu);
- const len_val = try mod.intValue(Type.usize, array_ty.arrayLen(mod));
- try f.writeCValueMember(writer, local, .{ .identifier = "len" });
- try writer.print(" = {};\n", .{try f.fmtIntLiteral(Type.usize, len_val)});
+ {
+ const a = try Assignment.start(f, writer, ptr_ty);
+ try f.writeCValueMember(writer, local, .{ .identifier = "ptr" });
+ try a.assign(f, writer);
+ if (operand == .undef) {
+ try f.writeCValue(writer, .{ .undef = inst_ty.slicePtrFieldType(zcu) }, .Initializer);
+ } else {
+ const ptr_cty = try f.typeToIndex(ptr_ty, .complete);
+ const ptr_child_cty = f.indexToCType(ptr_cty).cast(CType.Payload.Child).?.data;
+ const elem_ty = array_ty.childType(zcu);
+ const elem_cty = try f.typeToIndex(elem_ty, .complete);
+ if (ptr_child_cty != elem_cty) {
+ try writer.writeByte('(');
+ try f.renderCType(writer, ptr_cty);
+ try writer.writeByte(')');
+ }
+ const operand_cty = try f.typeToCType(operand_ty, .complete);
+ const operand_child_cty = operand_cty.cast(CType.Payload.Child).?.data;
+ if (f.indexToCType(operand_child_cty).tag() == .array) {
+ try writer.writeByte('&');
+ try f.writeCValueDeref(writer, operand);
+ try writer.print("[{}]", .{try f.fmtIntLiteral(try zcu.intValue(Type.usize, 0))});
+ } else try f.writeCValue(writer, operand, .Initializer);
+ }
+ try a.end(f, writer);
+ }
+ {
+ const a = try Assignment.start(f, writer, Type.usize);
+ try f.writeCValueMember(writer, local, .{ .identifier = "len" });
+ try a.assign(f, writer);
+ try writer.print("{}", .{
+ try f.fmtIntLiteral(try zcu.intValue(Type.usize, array_ty.arrayLen(zcu))),
+ });
+ try a.end(f, writer);
+ }
return local;
}
fn airFloatCast(f: *Function, inst: Air.Inst.Index) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const inst_ty = f.typeOfIndex(inst);
- const inst_scalar_ty = inst_ty.scalarType(mod);
+ const inst_scalar_ty = inst_ty.scalarType(zcu);
const operand = try f.resolveInst(ty_op.operand);
try reap(f, inst, &.{ty_op.operand});
const operand_ty = f.typeOf(ty_op.operand);
- const scalar_ty = operand_ty.scalarType(mod);
- const target = f.object.dg.module.getTarget();
+ const scalar_ty = operand_ty.scalarType(zcu);
+ const target = &f.object.dg.mod.resolved_target.result;
const operation = if (inst_scalar_ty.isRuntimeFloat() and scalar_ty.isRuntimeFloat())
- if (inst_scalar_ty.floatBits(target) < scalar_ty.floatBits(target)) "trunc" else "extend"
- else if (inst_scalar_ty.isInt(mod) and scalar_ty.isRuntimeFloat())
- if (inst_scalar_ty.isSignedInt(mod)) "fix" else "fixuns"
- else if (inst_scalar_ty.isRuntimeFloat() and scalar_ty.isInt(mod))
- if (scalar_ty.isSignedInt(mod)) "float" else "floatun"
+ if (inst_scalar_ty.floatBits(target.*) < scalar_ty.floatBits(target.*)) "trunc" else "extend"
+ else if (inst_scalar_ty.isInt(zcu) and scalar_ty.isRuntimeFloat())
+ if (inst_scalar_ty.isSignedInt(zcu)) "fix" else "fixuns"
+ else if (inst_scalar_ty.isRuntimeFloat() and scalar_ty.isInt(zcu))
+ if (scalar_ty.isSignedInt(zcu)) "float" else "floatun"
else
unreachable;
@@ -6082,20 +6166,20 @@ fn airFloatCast(f: *Function, inst: Air.Inst.Index) !CValue {
try f.writeCValue(writer, local, .Other);
try v.elem(f, writer);
try a.assign(f, writer);
- if (inst_scalar_ty.isInt(mod) and scalar_ty.isRuntimeFloat()) {
+ if (inst_scalar_ty.isInt(zcu) and scalar_ty.isRuntimeFloat()) {
try writer.writeAll("zig_wrap_");
try f.object.dg.renderTypeForBuiltinFnName(writer, inst_scalar_ty);
try writer.writeByte('(');
}
try writer.writeAll("zig_");
try writer.writeAll(operation);
- try writer.writeAll(compilerRtAbbrev(scalar_ty, mod));
- try writer.writeAll(compilerRtAbbrev(inst_scalar_ty, mod));
+ try writer.writeAll(compilerRtAbbrev(scalar_ty, zcu, target.*));
+ try writer.writeAll(compilerRtAbbrev(inst_scalar_ty, zcu, target.*));
try writer.writeByte('(');
try f.writeCValue(writer, operand, .FunctionArgument);
try v.elem(f, writer);
try writer.writeByte(')');
- if (inst_scalar_ty.isInt(mod) and scalar_ty.isRuntimeFloat()) {
+ if (inst_scalar_ty.isInt(zcu) and scalar_ty.isRuntimeFloat()) {
try f.object.dg.renderBuiltinInfo(writer, inst_scalar_ty, .bits);
try writer.writeByte(')');
}
@@ -6106,7 +6190,7 @@ fn airFloatCast(f: *Function, inst: Air.Inst.Index) !CValue {
}
fn airIntFromPtr(f: *Function, inst: Air.Inst.Index) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const operand = try f.resolveInst(un_op);
@@ -6120,7 +6204,7 @@ fn airIntFromPtr(f: *Function, inst: Air.Inst.Index) !CValue {
try writer.writeAll(" = (");
try f.renderType(writer, inst_ty);
try writer.writeByte(')');
- if (operand_ty.isSlice(mod)) {
+ if (operand_ty.isSlice(zcu)) {
try f.writeCValueMember(writer, operand, .{ .identifier = "ptr" });
} else {
try f.writeCValue(writer, operand, .Other);
@@ -6135,15 +6219,15 @@ fn airUnBuiltinCall(
operation: []const u8,
info: BuiltinInfo,
) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const operand = try f.resolveInst(ty_op.operand);
try reap(f, inst, &.{ty_op.operand});
const inst_ty = f.typeOfIndex(inst);
- const inst_scalar_ty = inst_ty.scalarType(mod);
+ const inst_scalar_ty = inst_ty.scalarType(zcu);
const operand_ty = f.typeOf(ty_op.operand);
- const scalar_ty = operand_ty.scalarType(mod);
+ const scalar_ty = operand_ty.scalarType(zcu);
const inst_scalar_cty = try f.typeToCType(inst_scalar_ty, .complete);
const ref_ret = inst_scalar_cty.tag() == .array;
@@ -6179,7 +6263,7 @@ fn airBinBuiltinCall(
operation: []const u8,
info: BuiltinInfo,
) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const operand_ty = f.typeOf(bin_op.lhs);
@@ -6191,8 +6275,8 @@ fn airBinBuiltinCall(
if (!is_big) try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
const inst_ty = f.typeOfIndex(inst);
- const inst_scalar_ty = inst_ty.scalarType(mod);
- const scalar_ty = operand_ty.scalarType(mod);
+ const inst_scalar_ty = inst_ty.scalarType(zcu);
+ const scalar_ty = operand_ty.scalarType(zcu);
const inst_scalar_cty = try f.typeToCType(inst_scalar_ty, .complete);
const ref_ret = inst_scalar_cty.tag() == .array;
@@ -6234,15 +6318,15 @@ fn airCmpBuiltinCall(
operation: enum { cmp, operator },
info: BuiltinInfo,
) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const lhs = try f.resolveInst(data.lhs);
const rhs = try f.resolveInst(data.rhs);
try reap(f, inst, &.{ data.lhs, data.rhs });
const inst_ty = f.typeOfIndex(inst);
- const inst_scalar_ty = inst_ty.scalarType(mod);
+ const inst_scalar_ty = inst_ty.scalarType(zcu);
const operand_ty = f.typeOf(data.lhs);
- const scalar_ty = operand_ty.scalarType(mod);
+ const scalar_ty = operand_ty.scalarType(zcu);
const inst_scalar_cty = try f.typeToCType(inst_scalar_ty, .complete);
const ref_ret = inst_scalar_cty.tag() == .array;
@@ -6275,7 +6359,7 @@ fn airCmpBuiltinCall(
try writer.writeByte(')');
if (!ref_ret) try writer.print("{s}{}", .{
compareOperatorC(operator),
- try f.fmtIntLiteral(Type.i32, try mod.intValue(Type.i32, 0)),
+ try f.fmtIntLiteral(try zcu.intValue(Type.i32, 0)),
});
try writer.writeAll(";\n");
try v.end(f, inst, writer);
@@ -6284,7 +6368,7 @@ fn airCmpBuiltinCall(
}
fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = f.air.extraData(Air.Cmpxchg, ty_pl.payload).data;
const inst_ty = f.typeOfIndex(inst);
@@ -6292,19 +6376,19 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue
const expected_value = try f.resolveInst(extra.expected_value);
const new_value = try f.resolveInst(extra.new_value);
const ptr_ty = f.typeOf(extra.ptr);
- const ty = ptr_ty.childType(mod);
+ const ty = ptr_ty.childType(zcu);
const writer = f.object.writer();
const new_value_mat = try Materialize.start(f, inst, writer, ty, new_value);
try reap(f, inst, &.{ extra.ptr, extra.expected_value, extra.new_value });
const repr_ty = if (ty.isRuntimeFloat())
- mod.intType(.unsigned, @as(u16, @intCast(ty.abiSize(mod) * 8))) catch unreachable
+ zcu.intType(.unsigned, @as(u16, @intCast(ty.abiSize(zcu) * 8))) catch unreachable
else
ty;
const local = try f.allocLocal(inst, inst_ty);
- if (inst_ty.isPtrLikeOptional(mod)) {
+ if (inst_ty.isPtrLikeOptional(zcu)) {
{
const a = try Assignment.start(f, writer, ty);
try f.writeCValue(writer, local, .Other);
@@ -6317,7 +6401,7 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue
try writer.print("zig_cmpxchg_{s}((zig_atomic(", .{flavor});
try f.renderType(writer, ty);
try writer.writeByte(')');
- if (ptr_ty.isVolatilePtr(mod)) try writer.writeAll(" volatile");
+ if (ptr_ty.isVolatilePtr(zcu)) try writer.writeAll(" volatile");
try writer.writeAll(" *)");
try f.writeCValue(writer, ptr, .Other);
try writer.writeAll(", ");
@@ -6331,7 +6415,7 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue
try writer.writeAll(", ");
try f.object.dg.renderTypeForBuiltinFnName(writer, ty);
try writer.writeAll(", ");
- try f.object.dg.renderType(writer, repr_ty);
+ try f.renderType(writer, repr_ty);
try writer.writeByte(')');
try writer.writeAll(") {\n");
f.object.indent_writer.pushIndent();
@@ -6359,7 +6443,7 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue
try writer.print("zig_cmpxchg_{s}((zig_atomic(", .{flavor});
try f.renderType(writer, ty);
try writer.writeByte(')');
- if (ptr_ty.isVolatilePtr(mod)) try writer.writeAll(" volatile");
+ if (ptr_ty.isVolatilePtr(zcu)) try writer.writeAll(" volatile");
try writer.writeAll(" *)");
try f.writeCValue(writer, ptr, .Other);
try writer.writeAll(", ");
@@ -6373,7 +6457,7 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue
try writer.writeAll(", ");
try f.object.dg.renderTypeForBuiltinFnName(writer, ty);
try writer.writeAll(", ");
- try f.object.dg.renderType(writer, repr_ty);
+ try f.renderType(writer, repr_ty);
try writer.writeByte(')');
try a.end(f, writer);
}
@@ -6389,12 +6473,12 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue
}
fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
const extra = f.air.extraData(Air.AtomicRmw, pl_op.payload).data;
const inst_ty = f.typeOfIndex(inst);
const ptr_ty = f.typeOf(pl_op.operand);
- const ty = ptr_ty.childType(mod);
+ const ty = ptr_ty.childType(zcu);
const ptr = try f.resolveInst(pl_op.operand);
const operand = try f.resolveInst(extra.operand);
@@ -6402,10 +6486,10 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {
const operand_mat = try Materialize.start(f, inst, writer, ty, operand);
try reap(f, inst, &.{ pl_op.operand, extra.operand });
- const repr_bits = @as(u16, @intCast(ty.abiSize(mod) * 8));
+ const repr_bits = @as(u16, @intCast(ty.abiSize(zcu) * 8));
const is_float = ty.isRuntimeFloat();
const is_128 = repr_bits == 128;
- const repr_ty = if (is_float) mod.intType(.unsigned, repr_bits) catch unreachable else ty;
+ const repr_ty = if (is_float) zcu.intType(.unsigned, repr_bits) catch unreachable else ty;
const local = try f.allocLocal(inst, inst_ty);
try writer.print("zig_atomicrmw_{s}", .{toAtomicRmwSuffix(extra.op())});
@@ -6421,7 +6505,7 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {
if (use_atomic) try writer.writeAll("zig_atomic(");
try f.renderType(writer, ty);
if (use_atomic) try writer.writeByte(')');
- if (ptr_ty.isVolatilePtr(mod)) try writer.writeAll(" volatile");
+ if (ptr_ty.isVolatilePtr(zcu)) try writer.writeAll(" volatile");
try writer.writeAll(" *)");
try f.writeCValue(writer, ptr, .Other);
try writer.writeAll(", ");
@@ -6431,7 +6515,7 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {
try writer.writeAll(", ");
try f.object.dg.renderTypeForBuiltinFnName(writer, ty);
try writer.writeAll(", ");
- try f.object.dg.renderType(writer, repr_ty);
+ try f.renderType(writer, repr_ty);
try writer.writeAll(");\n");
try operand_mat.end(f, inst);
@@ -6444,15 +6528,15 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {
}
fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const atomic_load = f.air.instructions.items(.data)[@intFromEnum(inst)].atomic_load;
const ptr = try f.resolveInst(atomic_load.ptr);
try reap(f, inst, &.{atomic_load.ptr});
const ptr_ty = f.typeOf(atomic_load.ptr);
- const ty = ptr_ty.childType(mod);
+ const ty = ptr_ty.childType(zcu);
const repr_ty = if (ty.isRuntimeFloat())
- mod.intType(.unsigned, @as(u16, @intCast(ty.abiSize(mod) * 8))) catch unreachable
+ zcu.intType(.unsigned, @as(u16, @intCast(ty.abiSize(zcu) * 8))) catch unreachable
else
ty;
@@ -6465,7 +6549,7 @@ fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue {
try writer.writeAll(", (zig_atomic(");
try f.renderType(writer, ty);
try writer.writeByte(')');
- if (ptr_ty.isVolatilePtr(mod)) try writer.writeAll(" volatile");
+ if (ptr_ty.isVolatilePtr(zcu)) try writer.writeAll(" volatile");
try writer.writeAll(" *)");
try f.writeCValue(writer, ptr, .Other);
try writer.writeAll(", ");
@@ -6473,17 +6557,17 @@ fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue {
try writer.writeAll(", ");
try f.object.dg.renderTypeForBuiltinFnName(writer, ty);
try writer.writeAll(", ");
- try f.object.dg.renderType(writer, repr_ty);
+ try f.renderType(writer, repr_ty);
try writer.writeAll(");\n");
return local;
}
fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const ptr_ty = f.typeOf(bin_op.lhs);
- const ty = ptr_ty.childType(mod);
+ const ty = ptr_ty.childType(zcu);
const ptr = try f.resolveInst(bin_op.lhs);
const element = try f.resolveInst(bin_op.rhs);
@@ -6492,14 +6576,14 @@ fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CVa
try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
const repr_ty = if (ty.isRuntimeFloat())
- mod.intType(.unsigned, @as(u16, @intCast(ty.abiSize(mod) * 8))) catch unreachable
+ zcu.intType(.unsigned, @as(u16, @intCast(ty.abiSize(zcu) * 8))) catch unreachable
else
ty;
try writer.writeAll("zig_atomic_store((zig_atomic(");
try f.renderType(writer, ty);
try writer.writeByte(')');
- if (ptr_ty.isVolatilePtr(mod)) try writer.writeAll(" volatile");
+ if (ptr_ty.isVolatilePtr(zcu)) try writer.writeAll(" volatile");
try writer.writeAll(" *)");
try f.writeCValue(writer, ptr, .Other);
try writer.writeAll(", ");
@@ -6507,7 +6591,7 @@ fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CVa
try writer.print(", {s}, ", .{order});
try f.object.dg.renderTypeForBuiltinFnName(writer, ty);
try writer.writeAll(", ");
- try f.object.dg.renderType(writer, repr_ty);
+ try f.renderType(writer, repr_ty);
try writer.writeAll(");\n");
try element_mat.end(f, inst);
@@ -6515,8 +6599,8 @@ fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CVa
}
fn writeSliceOrPtr(f: *Function, writer: anytype, ptr: CValue, ptr_ty: Type) !void {
- const mod = f.object.dg.module;
- if (ptr_ty.isSlice(mod)) {
+ const zcu = f.object.dg.zcu;
+ if (ptr_ty.isSlice(zcu)) {
try f.writeCValueMember(writer, ptr, .{ .identifier = "ptr" });
} else {
try f.writeCValue(writer, ptr, .FunctionArgument);
@@ -6524,14 +6608,14 @@ fn writeSliceOrPtr(f: *Function, writer: anytype, ptr: CValue, ptr_ty: Type) !vo
}
fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const dest_ty = f.typeOf(bin_op.lhs);
const dest_slice = try f.resolveInst(bin_op.lhs);
const value = try f.resolveInst(bin_op.rhs);
const elem_ty = f.typeOf(bin_op.rhs);
- const elem_abi_size = elem_ty.abiSize(mod);
- const val_is_undef = if (try f.air.value(bin_op.rhs, mod)) |val| val.isUndefDeep(mod) else false;
+ const elem_abi_size = elem_ty.abiSize(zcu);
+ const val_is_undef = if (try f.air.value(bin_op.rhs, zcu)) |val| val.isUndefDeep(zcu) else false;
const writer = f.object.writer();
if (val_is_undef) {
@@ -6541,7 +6625,7 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
}
try writer.writeAll("memset(");
- switch (dest_ty.ptrSize(mod)) {
+ switch (dest_ty.ptrSize(zcu)) {
.Slice => {
try f.writeCValueMember(writer, dest_slice, .{ .identifier = "ptr" });
try writer.writeAll(", 0xaa, ");
@@ -6553,8 +6637,8 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
}
},
.One => {
- const array_ty = dest_ty.childType(mod);
- const len = array_ty.arrayLen(mod) * elem_abi_size;
+ const array_ty = dest_ty.childType(zcu);
+ const len = array_ty.arrayLen(zcu) * elem_abi_size;
try f.writeCValue(writer, dest_slice, .FunctionArgument);
try writer.print(", 0xaa, {d});\n", .{len});
@@ -6565,12 +6649,12 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
return .none;
}
- if (elem_abi_size > 1 or dest_ty.isVolatilePtr(mod)) {
+ if (elem_abi_size > 1 or dest_ty.isVolatilePtr(zcu)) {
// For the assignment in this loop, the array pointer needs to get
// casted to a regular pointer, otherwise an error like this occurs:
// error: array type 'uint32_t[20]' (aka 'unsigned int[20]') is not assignable
- const elem_ptr_ty = try mod.ptrType(.{
- .child = elem_ty.ip_index,
+ const elem_ptr_ty = try zcu.ptrType(.{
+ .child = elem_ty.toIntern(),
.flags = .{
.size = .C,
},
@@ -6581,17 +6665,17 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
try writer.writeAll("for (");
try f.writeCValue(writer, index, .Other);
try writer.writeAll(" = ");
- try f.object.dg.renderValue(writer, Type.usize, try mod.intValue(Type.usize, 0), .Initializer);
+ try f.object.dg.renderValue(writer, try zcu.intValue(Type.usize, 0), .Initializer);
try writer.writeAll("; ");
try f.writeCValue(writer, index, .Other);
try writer.writeAll(" != ");
- switch (dest_ty.ptrSize(mod)) {
+ switch (dest_ty.ptrSize(zcu)) {
.Slice => {
try f.writeCValueMember(writer, dest_slice, .{ .identifier = "len" });
},
.One => {
- const array_ty = dest_ty.childType(mod);
- try writer.print("{d}", .{array_ty.arrayLen(mod)});
+ const array_ty = dest_ty.childType(zcu);
+ try writer.print("{d}", .{array_ty.arrayLen(zcu)});
},
.Many, .C => unreachable,
}
@@ -6620,7 +6704,7 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
const bitcasted = try bitcast(f, Type.u8, value, elem_ty);
try writer.writeAll("memset(");
- switch (dest_ty.ptrSize(mod)) {
+ switch (dest_ty.ptrSize(zcu)) {
.Slice => {
try f.writeCValueMember(writer, dest_slice, .{ .identifier = "ptr" });
try writer.writeAll(", ");
@@ -6630,8 +6714,8 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
try writer.writeAll(");\n");
},
.One => {
- const array_ty = dest_ty.childType(mod);
- const len = array_ty.arrayLen(mod) * elem_abi_size;
+ const array_ty = dest_ty.childType(zcu);
+ const len = array_ty.arrayLen(zcu) * elem_abi_size;
try f.writeCValue(writer, dest_slice, .FunctionArgument);
try writer.writeAll(", ");
@@ -6646,7 +6730,7 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
}
fn airMemcpy(f: *Function, inst: Air.Inst.Index) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const dest_ptr = try f.resolveInst(bin_op.lhs);
const src_ptr = try f.resolveInst(bin_op.rhs);
@@ -6659,10 +6743,10 @@ fn airMemcpy(f: *Function, inst: Air.Inst.Index) !CValue {
try writer.writeAll(", ");
try writeSliceOrPtr(f, writer, src_ptr, src_ty);
try writer.writeAll(", ");
- switch (dest_ty.ptrSize(mod)) {
+ switch (dest_ty.ptrSize(zcu)) {
.Slice => {
- const elem_ty = dest_ty.childType(mod);
- const elem_abi_size = elem_ty.abiSize(mod);
+ const elem_ty = dest_ty.childType(zcu);
+ const elem_abi_size = elem_ty.abiSize(zcu);
try f.writeCValueMember(writer, dest_ptr, .{ .identifier = "len" });
if (elem_abi_size > 1) {
try writer.print(" * {d});\n", .{elem_abi_size});
@@ -6671,10 +6755,10 @@ fn airMemcpy(f: *Function, inst: Air.Inst.Index) !CValue {
}
},
.One => {
- const array_ty = dest_ty.childType(mod);
- const elem_ty = array_ty.childType(mod);
- const elem_abi_size = elem_ty.abiSize(mod);
- const len = array_ty.arrayLen(mod) * elem_abi_size;
+ const array_ty = dest_ty.childType(zcu);
+ const elem_ty = array_ty.childType(zcu);
+ const elem_abi_size = elem_ty.abiSize(zcu);
+ const len = array_ty.arrayLen(zcu) * elem_abi_size;
try writer.print("{d});\n", .{len});
},
.Many, .C => unreachable,
@@ -6685,16 +6769,16 @@ fn airMemcpy(f: *Function, inst: Air.Inst.Index) !CValue {
}
fn airSetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const union_ptr = try f.resolveInst(bin_op.lhs);
const new_tag = try f.resolveInst(bin_op.rhs);
try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
- const union_ty = f.typeOf(bin_op.lhs).childType(mod);
- const layout = union_ty.unionGetLayout(mod);
+ const union_ty = f.typeOf(bin_op.lhs).childType(zcu);
+ const layout = union_ty.unionGetLayout(zcu);
if (layout.tag_size == 0) return .none;
- const tag_ty = union_ty.unionTagTypeSafety(mod).?;
+ const tag_ty = union_ty.unionTagTypeSafety(zcu).?;
const writer = f.object.writer();
const a = try Assignment.start(f, writer, tag_ty);
@@ -6706,14 +6790,14 @@ fn airSetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {
}
fn airGetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const operand = try f.resolveInst(ty_op.operand);
try reap(f, inst, &.{ty_op.operand});
const union_ty = f.typeOf(ty_op.operand);
- const layout = union_ty.unionGetLayout(mod);
+ const layout = union_ty.unionGetLayout(zcu);
if (layout.tag_size == 0) return .none;
const inst_ty = f.typeOfIndex(inst);
@@ -6728,7 +6812,7 @@ fn airGetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {
}
fn airTagName(f: *Function, inst: Air.Inst.Index) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const inst_ty = f.typeOfIndex(inst);
@@ -6740,7 +6824,7 @@ fn airTagName(f: *Function, inst: Air.Inst.Index) !CValue {
const local = try f.allocLocal(inst, inst_ty);
try f.writeCValue(writer, local, .Other);
try writer.print(" = {s}(", .{
- try f.getLazyFnName(.{ .tag_name = enum_ty.getOwnerDecl(mod) }, .{ .tag_name = enum_ty }),
+ try f.getLazyFnName(.{ .tag_name = enum_ty.getOwnerDecl(zcu) }, .{ .tag_name = enum_ty }),
});
try f.writeCValue(writer, operand, .Other);
try writer.writeAll(");\n");
@@ -6765,14 +6849,14 @@ fn airErrorName(f: *Function, inst: Air.Inst.Index) !CValue {
}
fn airSplat(f: *Function, inst: Air.Inst.Index) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const operand = try f.resolveInst(ty_op.operand);
try reap(f, inst, &.{ty_op.operand});
const inst_ty = f.typeOfIndex(inst);
- const inst_scalar_ty = inst_ty.scalarType(mod);
+ const inst_scalar_ty = inst_ty.scalarType(zcu);
const writer = f.object.writer();
const local = try f.allocLocal(inst, inst_ty);
@@ -6820,7 +6904,7 @@ fn airSelect(f: *Function, inst: Air.Inst.Index) !CValue {
}
fn airShuffle(f: *Function, inst: Air.Inst.Index) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = f.air.extraData(Air.Shuffle, ty_pl.payload).data;
@@ -6836,15 +6920,15 @@ fn airShuffle(f: *Function, inst: Air.Inst.Index) !CValue {
for (0..extra.mask_len) |index| {
try f.writeCValue(writer, local, .Other);
try writer.writeByte('[');
- try f.object.dg.renderValue(writer, Type.usize, try mod.intValue(Type.usize, index), .Other);
+ try f.object.dg.renderValue(writer, try zcu.intValue(Type.usize, index), .Other);
try writer.writeAll("] = ");
- const mask_elem = (try mask.elemValue(mod, index)).toSignedInt(mod);
- const src_val = try mod.intValue(Type.usize, @as(u64, @intCast(mask_elem ^ mask_elem >> 63)));
+ const mask_elem = (try mask.elemValue(zcu, index)).toSignedInt(zcu);
+ const src_val = try zcu.intValue(Type.usize, @as(u64, @intCast(mask_elem ^ mask_elem >> 63)));
try f.writeCValue(writer, if (mask_elem >= 0) lhs else rhs, .Other);
try writer.writeByte('[');
- try f.object.dg.renderValue(writer, Type.usize, src_val, .Other);
+ try f.object.dg.renderValue(writer, src_val, .Other);
try writer.writeAll("];\n");
}
@@ -6852,7 +6936,7 @@ fn airShuffle(f: *Function, inst: Air.Inst.Index) !CValue {
}
fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const reduce = f.air.instructions.items(.data)[@intFromEnum(inst)].reduce;
const scalar_ty = f.typeOfIndex(inst);
@@ -6861,7 +6945,7 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
const operand_ty = f.typeOf(reduce.operand);
const writer = f.object.writer();
- const use_operator = scalar_ty.bitSize(mod) <= 64;
+ const use_operator = scalar_ty.bitSize(zcu) <= 64;
const op: union(enum) {
const Func = struct { operation: []const u8, info: BuiltinInfo = .none };
float_op: Func,
@@ -6872,28 +6956,28 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
.And => if (use_operator) .{ .infix = " &= " } else .{ .builtin = .{ .operation = "and" } },
.Or => if (use_operator) .{ .infix = " |= " } else .{ .builtin = .{ .operation = "or" } },
.Xor => if (use_operator) .{ .infix = " ^= " } else .{ .builtin = .{ .operation = "xor" } },
- .Min => switch (scalar_ty.zigTypeTag(mod)) {
+ .Min => switch (scalar_ty.zigTypeTag(zcu)) {
.Int => if (use_operator) .{ .ternary = " < " } else .{
.builtin = .{ .operation = "min" },
},
.Float => .{ .float_op = .{ .operation = "fmin" } },
else => unreachable,
},
- .Max => switch (scalar_ty.zigTypeTag(mod)) {
+ .Max => switch (scalar_ty.zigTypeTag(zcu)) {
.Int => if (use_operator) .{ .ternary = " > " } else .{
.builtin = .{ .operation = "max" },
},
.Float => .{ .float_op = .{ .operation = "fmax" } },
else => unreachable,
},
- .Add => switch (scalar_ty.zigTypeTag(mod)) {
+ .Add => switch (scalar_ty.zigTypeTag(zcu)) {
.Int => if (use_operator) .{ .infix = " += " } else .{
.builtin = .{ .operation = "addw", .info = .bits },
},
.Float => .{ .builtin = .{ .operation = "add" } },
else => unreachable,
},
- .Mul => switch (scalar_ty.zigTypeTag(mod)) {
+ .Mul => switch (scalar_ty.zigTypeTag(zcu)) {
.Int => if (use_operator) .{ .infix = " *= " } else .{
.builtin = .{ .operation = "mulw", .info = .bits },
},
@@ -6908,7 +6992,7 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
// Equivalent to:
// reduce: {
// var accum: T = init;
- // for (vec) : (elem) {
+ // for (vec) |elem| {
// accum = func(accum, elem);
// }
// break :reduce accum;
@@ -6918,40 +7002,40 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
try f.writeCValue(writer, accum, .Other);
try writer.writeAll(" = ");
- try f.object.dg.renderValue(writer, scalar_ty, switch (reduce.operation) {
- .Or, .Xor => switch (scalar_ty.zigTypeTag(mod)) {
+ try f.object.dg.renderValue(writer, switch (reduce.operation) {
+ .Or, .Xor => switch (scalar_ty.zigTypeTag(zcu)) {
.Bool => Value.false,
- .Int => try mod.intValue(scalar_ty, 0),
+ .Int => try zcu.intValue(scalar_ty, 0),
else => unreachable,
},
- .And => switch (scalar_ty.zigTypeTag(mod)) {
+ .And => switch (scalar_ty.zigTypeTag(zcu)) {
.Bool => Value.true,
- .Int => switch (scalar_ty.intInfo(mod).signedness) {
- .unsigned => try scalar_ty.maxIntScalar(mod, scalar_ty),
- .signed => try mod.intValue(scalar_ty, -1),
+ .Int => switch (scalar_ty.intInfo(zcu).signedness) {
+ .unsigned => try scalar_ty.maxIntScalar(zcu, scalar_ty),
+ .signed => try zcu.intValue(scalar_ty, -1),
},
else => unreachable,
},
- .Add => switch (scalar_ty.zigTypeTag(mod)) {
- .Int => try mod.intValue(scalar_ty, 0),
- .Float => try mod.floatValue(scalar_ty, 0.0),
+ .Add => switch (scalar_ty.zigTypeTag(zcu)) {
+ .Int => try zcu.intValue(scalar_ty, 0),
+ .Float => try zcu.floatValue(scalar_ty, 0.0),
else => unreachable,
},
- .Mul => switch (scalar_ty.zigTypeTag(mod)) {
- .Int => try mod.intValue(scalar_ty, 1),
- .Float => try mod.floatValue(scalar_ty, 1.0),
+ .Mul => switch (scalar_ty.zigTypeTag(zcu)) {
+ .Int => try zcu.intValue(scalar_ty, 1),
+ .Float => try zcu.floatValue(scalar_ty, 1.0),
else => unreachable,
},
- .Min => switch (scalar_ty.zigTypeTag(mod)) {
+ .Min => switch (scalar_ty.zigTypeTag(zcu)) {
.Bool => Value.true,
- .Int => try scalar_ty.maxIntScalar(mod, scalar_ty),
- .Float => try mod.floatValue(scalar_ty, std.math.nan(f128)),
+ .Int => try scalar_ty.maxIntScalar(zcu, scalar_ty),
+ .Float => try zcu.floatValue(scalar_ty, std.math.nan(f128)),
else => unreachable,
},
- .Max => switch (scalar_ty.zigTypeTag(mod)) {
+ .Max => switch (scalar_ty.zigTypeTag(zcu)) {
.Bool => Value.false,
- .Int => try scalar_ty.minIntScalar(mod, scalar_ty),
- .Float => try mod.floatValue(scalar_ty, std.math.nan(f128)),
+ .Int => try scalar_ty.minIntScalar(zcu, scalar_ty),
+ .Float => try zcu.floatValue(scalar_ty, std.math.nan(f128)),
else => unreachable,
},
}, .Initializer);
@@ -7007,11 +7091,11 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
}
fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
- const mod = f.object.dg.module;
- const ip = &mod.intern_pool;
+ const zcu = f.object.dg.zcu;
+ const ip = &zcu.intern_pool;
const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const inst_ty = f.typeOfIndex(inst);
- const len = @as(usize, @intCast(inst_ty.arrayLen(mod)));
+ const len = @as(usize, @intCast(inst_ty.arrayLen(zcu)));
const elements = @as([]const Air.Inst.Ref, @ptrCast(f.air.extra[ty_pl.payload..][0..len]));
const gpa = f.object.dg.gpa;
const resolved_elements = try gpa.alloc(CValue, elements.len);
@@ -7028,10 +7112,9 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
const writer = f.object.writer();
const local = try f.allocLocal(inst, inst_ty);
- switch (inst_ty.zigTypeTag(mod)) {
+ switch (inst_ty.zigTypeTag(zcu)) {
.Array, .Vector => {
- const elem_ty = inst_ty.childType(mod);
- const a = try Assignment.init(f, elem_ty);
+ const a = try Assignment.init(f, inst_ty.childType(zcu));
for (resolved_elements, 0..) |element, i| {
try a.restart(f, writer);
try f.writeCValue(writer, local, .Other);
@@ -7040,26 +7123,26 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
try f.writeCValue(writer, element, .Other);
try a.end(f, writer);
}
- if (inst_ty.sentinel(mod)) |sentinel| {
+ if (inst_ty.sentinel(zcu)) |sentinel| {
try a.restart(f, writer);
try f.writeCValue(writer, local, .Other);
try writer.print("[{d}]", .{resolved_elements.len});
try a.assign(f, writer);
- try f.object.dg.renderValue(writer, elem_ty, sentinel, .Other);
+ try f.object.dg.renderValue(writer, sentinel, .Other);
try a.end(f, writer);
}
},
- .Struct => switch (inst_ty.containerLayout(mod)) {
+ .Struct => switch (inst_ty.containerLayout(zcu)) {
.auto, .@"extern" => for (resolved_elements, 0..) |element, field_index| {
- if (inst_ty.structFieldIsComptime(field_index, mod)) continue;
- const field_ty = inst_ty.structFieldType(field_index, mod);
- if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
+ if (inst_ty.structFieldIsComptime(field_index, zcu)) continue;
+ const field_ty = inst_ty.structFieldType(field_index, zcu);
+ if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
const a = try Assignment.start(f, writer, field_ty);
- try f.writeCValueMember(writer, local, if (inst_ty.isSimpleTuple(mod))
+ try f.writeCValueMember(writer, local, if (inst_ty.isSimpleTuple(zcu))
.{ .field = field_index }
else
- .{ .identifier = ip.stringToSlice(inst_ty.legacyStructFieldName(@intCast(field_index), mod)) });
+ .{ .identifier = ip.stringToSlice(inst_ty.legacyStructFieldName(@intCast(field_index), zcu)) });
try a.assign(f, writer);
try f.writeCValue(writer, element, .Other);
try a.end(f, writer);
@@ -7067,17 +7150,17 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
.@"packed" => {
try f.writeCValue(writer, local, .Other);
try writer.writeAll(" = ");
- const int_info = inst_ty.intInfo(mod);
+ const int_info = inst_ty.intInfo(zcu);
- const bit_offset_ty = try mod.intType(.unsigned, Type.smallestUnsignedBits(int_info.bits - 1));
+ const bit_offset_ty = try zcu.intType(.unsigned, Type.smallestUnsignedBits(int_info.bits - 1));
var bit_offset: u64 = 0;
var empty = true;
for (0..elements.len) |field_index| {
- if (inst_ty.structFieldIsComptime(field_index, mod)) continue;
- const field_ty = inst_ty.structFieldType(field_index, mod);
- if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
+ if (inst_ty.structFieldIsComptime(field_index, zcu)) continue;
+ const field_ty = inst_ty.structFieldType(field_index, zcu);
+ if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
if (!empty) {
try writer.writeAll("zig_or_");
@@ -7088,9 +7171,9 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
}
empty = true;
for (resolved_elements, 0..) |element, field_index| {
- if (inst_ty.structFieldIsComptime(field_index, mod)) continue;
- const field_ty = inst_ty.structFieldType(field_index, mod);
- if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
+ if (inst_ty.structFieldIsComptime(field_index, zcu)) continue;
+ const field_ty = inst_ty.structFieldType(field_index, zcu);
+ if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
if (!empty) try writer.writeAll(", ");
// TODO: Skip this entire shift if val is 0?
@@ -7098,13 +7181,13 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
try f.object.dg.renderTypeForBuiltinFnName(writer, inst_ty);
try writer.writeByte('(');
- if (inst_ty.isAbiInt(mod) and (field_ty.isAbiInt(mod) or field_ty.isPtrAtRuntime(mod))) {
+ if (inst_ty.isAbiInt(zcu) and (field_ty.isAbiInt(zcu) or field_ty.isPtrAtRuntime(zcu))) {
try f.renderIntCast(writer, inst_ty, element, .{}, field_ty, .FunctionArgument);
} else {
try writer.writeByte('(');
try f.renderType(writer, inst_ty);
try writer.writeByte(')');
- if (field_ty.isPtrAtRuntime(mod)) {
+ if (field_ty.isPtrAtRuntime(zcu)) {
try writer.writeByte('(');
try f.renderType(writer, switch (int_info.signedness) {
.unsigned => Type.usize,
@@ -7115,14 +7198,14 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
try f.writeCValue(writer, element, .Other);
}
- try writer.writeAll(", ");
- const bit_offset_val = try mod.intValue(bit_offset_ty, bit_offset);
- try f.object.dg.renderValue(writer, bit_offset_ty, bit_offset_val, .FunctionArgument);
+ try writer.print(", {}", .{
+ try f.fmtIntLiteral(try zcu.intValue(bit_offset_ty, bit_offset)),
+ });
try f.object.dg.renderBuiltinInfo(writer, inst_ty, .bits);
try writer.writeByte(')');
if (!empty) try writer.writeByte(')');
- bit_offset += field_ty.bitSize(mod);
+ bit_offset += field_ty.bitSize(zcu);
empty = false;
}
@@ -7136,13 +7219,13 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
}
fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {
- const mod = f.object.dg.module;
- const ip = &mod.intern_pool;
+ const zcu = f.object.dg.zcu;
+ const ip = &zcu.intern_pool;
const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = f.air.extraData(Air.UnionInit, ty_pl.payload).data;
const union_ty = f.typeOfIndex(inst);
- const union_obj = mod.typeToUnion(union_ty).?;
+ const union_obj = zcu.typeToUnion(union_ty).?;
const field_name = union_obj.loadTagType(ip).names.get(ip)[extra.field_index];
const payload_ty = f.typeOf(extra.init);
const payload = try f.resolveInst(extra.init);
@@ -7158,19 +7241,16 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {
return local;
}
- const field: CValue = if (union_ty.unionTagTypeSafety(mod)) |tag_ty| field: {
- const layout = union_ty.unionGetLayout(mod);
+ const field: CValue = if (union_ty.unionTagTypeSafety(zcu)) |tag_ty| field: {
+ const layout = union_ty.unionGetLayout(zcu);
if (layout.tag_size != 0) {
- const field_index = tag_ty.enumFieldIndex(field_name, mod).?;
-
- const tag_val = try mod.enumValueFieldIndex(tag_ty, field_index);
-
- const int_val = try tag_val.intFromEnum(tag_ty, mod);
+ const field_index = tag_ty.enumFieldIndex(field_name, zcu).?;
+ const tag_val = try zcu.enumValueFieldIndex(tag_ty, field_index);
const a = try Assignment.start(f, writer, tag_ty);
try f.writeCValueMember(writer, local, .{ .identifier = "tag" });
try a.assign(f, writer);
- try writer.print("{}", .{try f.fmtIntLiteral(tag_ty, int_val)});
+ try writer.print("{}", .{try f.fmtIntLiteral(try tag_val.intFromEnum(tag_ty, zcu))});
try a.end(f, writer);
}
break :field .{ .payload_identifier = ip.stringToSlice(field_name) };
@@ -7185,7 +7265,7 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {
}
fn airPrefetch(f: *Function, inst: Air.Inst.Index) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const prefetch = f.air.instructions.items(.data)[@intFromEnum(inst)].prefetch;
const ptr_ty = f.typeOf(prefetch.ptr);
@@ -7196,7 +7276,7 @@ fn airPrefetch(f: *Function, inst: Air.Inst.Index) !CValue {
switch (prefetch.cache) {
.data => {
try writer.writeAll("zig_prefetch(");
- if (ptr_ty.isSlice(mod))
+ if (ptr_ty.isSlice(zcu))
try f.writeCValueMember(writer, ptr, .{ .identifier = "ptr" })
else
try f.writeCValue(writer, ptr, .FunctionArgument);
@@ -7242,14 +7322,14 @@ fn airWasmMemoryGrow(f: *Function, inst: Air.Inst.Index) !CValue {
}
fn airFloatNeg(f: *Function, inst: Air.Inst.Index) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const operand = try f.resolveInst(un_op);
try reap(f, inst, &.{un_op});
const operand_ty = f.typeOf(un_op);
- const scalar_ty = operand_ty.scalarType(mod);
+ const scalar_ty = operand_ty.scalarType(zcu);
const writer = f.object.writer();
const local = try f.allocLocal(inst, operand_ty);
@@ -7268,15 +7348,15 @@ fn airFloatNeg(f: *Function, inst: Air.Inst.Index) !CValue {
}
fn airAbs(f: *Function, inst: Air.Inst.Index) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const operand = try f.resolveInst(ty_op.operand);
const ty = f.typeOf(ty_op.operand);
- const scalar_ty = ty.scalarType(mod);
+ const scalar_ty = ty.scalarType(zcu);
- switch (scalar_ty.zigTypeTag(mod)) {
- .Int => if (ty.zigTypeTag(mod) == .Vector) {
- return f.fail("TODO implement airAbs for '{}'", .{ty.fmt(mod)});
+ switch (scalar_ty.zigTypeTag(zcu)) {
+ .Int => if (ty.zigTypeTag(zcu) == .Vector) {
+ return f.fail("TODO implement airAbs for '{}'", .{ty.fmt(zcu)});
} else {
return airUnBuiltinCall(f, inst, "abs", .none);
},
@@ -7286,8 +7366,8 @@ fn airAbs(f: *Function, inst: Air.Inst.Index) !CValue {
}
fn unFloatOp(f: *Function, inst: Air.Inst.Index, operand: CValue, ty: Type, operation: []const u8) !CValue {
- const mod = f.object.dg.module;
- const scalar_ty = ty.scalarType(mod);
+ const zcu = f.object.dg.zcu;
+ const scalar_ty = ty.scalarType(zcu);
const writer = f.object.writer();
const local = try f.allocLocal(inst, ty);
@@ -7316,7 +7396,7 @@ fn airUnFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CVal
}
fn airBinFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const lhs = try f.resolveInst(bin_op.lhs);
@@ -7324,7 +7404,7 @@ fn airBinFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CVa
try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
const inst_ty = f.typeOfIndex(inst);
- const inst_scalar_ty = inst_ty.scalarType(mod);
+ const inst_scalar_ty = inst_ty.scalarType(zcu);
const writer = f.object.writer();
const local = try f.allocLocal(inst, inst_ty);
@@ -7346,7 +7426,7 @@ fn airBinFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CVa
}
fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
const bin_op = f.air.extraData(Air.Bin, pl_op.payload).data;
@@ -7356,7 +7436,7 @@ fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue {
try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs, pl_op.operand });
const inst_ty = f.typeOfIndex(inst);
- const inst_scalar_ty = inst_ty.scalarType(mod);
+ const inst_scalar_ty = inst_ty.scalarType(zcu);
const writer = f.object.writer();
const local = try f.allocLocal(inst, inst_ty);
@@ -7381,11 +7461,11 @@ fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue {
}
fn airCVaStart(f: *Function, inst: Air.Inst.Index) !CValue {
- const mod = f.object.dg.module;
+ const zcu = f.object.dg.zcu;
const inst_ty = f.typeOfIndex(inst);
const decl_index = f.object.dg.pass.decl;
- const decl = mod.declPtr(decl_index);
- const fn_cty = try f.typeToCType(decl.typeOf(mod), .complete);
+ const decl = zcu.declPtr(decl_index);
+ const fn_cty = try f.typeToCType(decl.typeOf(zcu), .complete);
const param_len = fn_cty.castTag(.varargs_function).?.data.param_types.len;
const writer = f.object.writer();
@@ -7589,9 +7669,8 @@ fn signAbbrev(signedness: std.builtin.Signedness) u8 {
};
}
-fn compilerRtAbbrev(ty: Type, mod: *Module) []const u8 {
- const target = mod.getTarget();
- return if (ty.isInt(mod)) switch (ty.intInfo(mod).bits) {
+fn compilerRtAbbrev(ty: Type, zcu: *Zcu, target: std.Target) []const u8 {
+ return if (ty.isInt(zcu)) switch (ty.intInfo(zcu).bits) {
1...32 => "si",
33...64 => "di",
65...128 => "ti",
@@ -7753,8 +7832,8 @@ fn formatIntLiteral(
options: std.fmt.FormatOptions,
writer: anytype,
) @TypeOf(writer).Error!void {
- const mod = data.dg.module;
- const target = mod.getTarget();
+ const zcu = data.dg.zcu;
+ const target = &data.dg.mod.resolved_target.result;
const ExpectedContents = struct {
const base = 10;
@@ -7774,7 +7853,7 @@ fn formatIntLiteral(
defer allocator.free(undef_limbs);
var int_buf: Value.BigIntSpace = undefined;
- const int = if (data.val.isUndefDeep(mod)) blk: {
+ const int = if (data.val.isUndefDeep(zcu)) blk: {
undef_limbs = try allocator.alloc(BigIntLimb, BigInt.calcTwosCompLimbCount(data.int_info.bits));
@memset(undef_limbs, undefPattern(BigIntLimb));
@@ -7785,10 +7864,10 @@ fn formatIntLiteral(
};
undef_int.truncate(undef_int.toConst(), data.int_info.signedness, data.int_info.bits);
break :blk undef_int.toConst();
- } else data.val.toBigInt(&int_buf, mod);
+ } else data.val.toBigInt(&int_buf, zcu);
assert(int.fitsInTwosComp(data.int_info.signedness, data.int_info.bits));
- const c_bits: usize = @intCast(data.cty.byteSize(data.dg.ctypes.set, target) * 8);
+ const c_bits: usize = @intCast(data.cty.byteSize(data.dg.ctypes.set, data.dg.mod) * 8);
var one_limbs: [BigInt.calcLimbLen(1)]BigIntLimb = undefined;
const one = BigInt.Mutable.init(&one_limbs, 1).toConst();
@@ -7919,7 +7998,7 @@ fn formatIntLiteral(
.int_info = c_limb_int_info,
.kind = data.kind,
.cty = c_limb_cty,
- .val = try mod.intValue_big(Type.comptime_int, c_limb_mut.toConst()),
+ .val = try zcu.intValue_big(Type.comptime_int, c_limb_mut.toConst()),
}, fmt, options, writer);
}
}
@@ -8016,21 +8095,17 @@ const Vectorize = struct {
index: CValue = .none,
pub fn start(f: *Function, inst: Air.Inst.Index, writer: anytype, ty: Type) !Vectorize {
- const mod = f.object.dg.module;
- return if (ty.zigTypeTag(mod) == .Vector) index: {
- const len_val = try mod.intValue(Type.usize, ty.vectorLen(mod));
-
+ const zcu = f.object.dg.zcu;
+ return if (ty.zigTypeTag(zcu) == .Vector) index: {
const local = try f.allocLocal(inst, Type.usize);
try writer.writeAll("for (");
try f.writeCValue(writer, local, .Other);
- try writer.print(" = {d}; ", .{try f.fmtIntLiteral(Type.usize, try mod.intValue(Type.usize, 0))});
+ try writer.print(" = {d}; ", .{try f.fmtIntLiteral(try zcu.intValue(Type.usize, 0))});
try f.writeCValue(writer, local, .Other);
- try writer.print(" < {d}; ", .{
- try f.fmtIntLiteral(Type.usize, len_val),
- });
+ try writer.print(" < {d}; ", .{try f.fmtIntLiteral(try zcu.intValue(Type.usize, ty.vectorLen(zcu)))});
try f.writeCValue(writer, local, .Other);
- try writer.print(" += {d}) {{\n", .{try f.fmtIntLiteral(Type.usize, try mod.intValue(Type.usize, 1))});
+ try writer.print(" += {d}) {{\n", .{try f.fmtIntLiteral(try zcu.intValue(Type.usize, 1))});
f.object.indent_writer.pushIndent();
break :index .{ .index = local };
@@ -8054,16 +8129,16 @@ const Vectorize = struct {
}
};
-fn lowerFnRetTy(ret_ty: Type, mod: *Module) !Type {
- if (ret_ty.ip_index == .noreturn_type) return Type.noreturn;
+fn lowerFnRetTy(ret_ty: Type, zcu: *Zcu) !Type {
+ if (ret_ty.toIntern() == .noreturn_type) return Type.noreturn;
- if (lowersToArray(ret_ty, mod)) {
- const gpa = mod.gpa;
- const ip = &mod.intern_pool;
+ if (lowersToArray(ret_ty, zcu)) {
+ const gpa = zcu.gpa;
+ const ip = &zcu.intern_pool;
const names = [1]InternPool.NullTerminatedString{
try ip.getOrPutString(gpa, "array"),
};
- const types = [1]InternPool.Index{ret_ty.ip_index};
+ const types = [1]InternPool.Index{ret_ty.toIntern()};
const values = [1]InternPool.Index{.none};
const interned = try ip.getAnonStructType(gpa, .{
.names = &names,
@@ -8073,13 +8148,13 @@ fn lowerFnRetTy(ret_ty: Type, mod: *Module) !Type {
return Type.fromInterned(interned);
}
- return if (ret_ty.hasRuntimeBitsIgnoreComptime(mod)) ret_ty else Type.void;
+ return if (ret_ty.hasRuntimeBitsIgnoreComptime(zcu)) ret_ty else Type.void;
}
-fn lowersToArray(ty: Type, mod: *Module) bool {
- return switch (ty.zigTypeTag(mod)) {
+fn lowersToArray(ty: Type, zcu: *Zcu) bool {
+ return switch (ty.zigTypeTag(zcu)) {
.Array, .Vector => return true,
- else => return ty.isAbiInt(mod) and toCIntBits(@as(u32, @intCast(ty.bitSize(mod)))) == null,
+ else => return ty.isAbiInt(zcu) and toCIntBits(@as(u32, @intCast(ty.bitSize(zcu)))) == null,
};
}
@@ -8098,7 +8173,7 @@ fn die(f: *Function, inst: Air.Inst.Index, ref: Air.Inst.Ref) !void {
const ref_inst = ref.toIndex() orelse return;
const c_value = (f.value_map.fetchRemove(ref) orelse return).value;
const local_index = switch (c_value) {
- .local, .new_local => |l| l,
+ .new_local, .local => |l| l,
else => return,
};
try freeLocal(f, inst, local_index, ref_inst);
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;
}
src/Compilation.zig
@@ -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,