mirror of
https://github.com/ziglang/zig.git
synced 2026-02-12 20:37:54 +00:00
stage2: move opaque types to InternPool
This commit is contained in:
parent
e94a81c951
commit
275652f620
@ -2048,7 +2048,7 @@ pub fn update(comp: *Compilation, main_progress_node: *std.Progress.Node) !void
|
||||
assert(decl.deletion_flag);
|
||||
assert(decl.dependants.count() == 0);
|
||||
const is_anon = if (decl.zir_decl_index == 0) blk: {
|
||||
break :blk decl.src_namespace.anon_decls.swapRemove(decl_index);
|
||||
break :blk module.namespacePtr(decl.src_namespace).anon_decls.swapRemove(decl_index);
|
||||
} else false;
|
||||
|
||||
try module.clearDecl(decl_index, null);
|
||||
@ -2530,8 +2530,7 @@ pub fn totalErrorCount(self: *Compilation) u32 {
|
||||
// the previous parse success, including compile errors, but we cannot
|
||||
// emit them until the file succeeds parsing.
|
||||
for (module.failed_decls.keys()) |key| {
|
||||
const decl = module.declPtr(key);
|
||||
if (decl.getFileScope().okToReportErrors()) {
|
||||
if (module.declFileScope(key).okToReportErrors()) {
|
||||
total += 1;
|
||||
if (module.cimport_errors.get(key)) |errors| {
|
||||
total += errors.len;
|
||||
@ -2540,8 +2539,7 @@ pub fn totalErrorCount(self: *Compilation) u32 {
|
||||
}
|
||||
if (module.emit_h) |emit_h| {
|
||||
for (emit_h.failed_decls.keys()) |key| {
|
||||
const decl = module.declPtr(key);
|
||||
if (decl.getFileScope().okToReportErrors()) {
|
||||
if (module.declFileScope(key).okToReportErrors()) {
|
||||
total += 1;
|
||||
}
|
||||
}
|
||||
@ -2644,10 +2642,10 @@ pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle {
|
||||
{
|
||||
var it = module.failed_decls.iterator();
|
||||
while (it.next()) |entry| {
|
||||
const decl = module.declPtr(entry.key_ptr.*);
|
||||
const decl_index = entry.key_ptr.*;
|
||||
// Skip errors for Decls within files that had a parse failure.
|
||||
// We'll try again once parsing succeeds.
|
||||
if (decl.getFileScope().okToReportErrors()) {
|
||||
if (module.declFileScope(decl_index).okToReportErrors()) {
|
||||
try addModuleErrorMsg(&bundle, entry.value_ptr.*.*);
|
||||
if (module.cimport_errors.get(entry.key_ptr.*)) |cimport_errors| for (cimport_errors) |c_error| {
|
||||
try bundle.addRootErrorMessage(.{
|
||||
@ -2669,10 +2667,10 @@ pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle {
|
||||
if (module.emit_h) |emit_h| {
|
||||
var it = emit_h.failed_decls.iterator();
|
||||
while (it.next()) |entry| {
|
||||
const decl = module.declPtr(entry.key_ptr.*);
|
||||
const decl_index = entry.key_ptr.*;
|
||||
// Skip errors for Decls within files that had a parse failure.
|
||||
// We'll try again once parsing succeeds.
|
||||
if (decl.getFileScope().okToReportErrors()) {
|
||||
if (module.declFileScope(decl_index).okToReportErrors()) {
|
||||
try addModuleErrorMsg(&bundle, entry.value_ptr.*.*);
|
||||
}
|
||||
}
|
||||
@ -2710,7 +2708,7 @@ pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle {
|
||||
const values = module.compile_log_decls.values();
|
||||
// First one will be the error; subsequent ones will be notes.
|
||||
const err_decl = module.declPtr(keys[0]);
|
||||
const src_loc = err_decl.nodeOffsetSrcLoc(values[0]);
|
||||
const src_loc = err_decl.nodeOffsetSrcLoc(values[0], module);
|
||||
const err_msg = Module.ErrorMsg{
|
||||
.src_loc = src_loc,
|
||||
.msg = "found compile log statement",
|
||||
@ -2721,7 +2719,7 @@ pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle {
|
||||
for (keys[1..], 0..) |key, i| {
|
||||
const note_decl = module.declPtr(key);
|
||||
err_msg.notes[i] = .{
|
||||
.src_loc = note_decl.nodeOffsetSrcLoc(values[i + 1]),
|
||||
.src_loc = note_decl.nodeOffsetSrcLoc(values[i + 1], module),
|
||||
.msg = "also here",
|
||||
};
|
||||
}
|
||||
@ -3235,7 +3233,7 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: *std.Progress.Node) !v
|
||||
try module.failed_decls.ensureUnusedCapacity(gpa, 1);
|
||||
module.failed_decls.putAssumeCapacityNoClobber(decl_index, try Module.ErrorMsg.create(
|
||||
gpa,
|
||||
decl.srcLoc(),
|
||||
decl.srcLoc(module),
|
||||
"unable to update line number: {s}",
|
||||
.{@errorName(err)},
|
||||
));
|
||||
@ -3848,7 +3846,7 @@ fn reportRetryableEmbedFileError(
|
||||
const mod = comp.bin_file.options.module.?;
|
||||
const gpa = mod.gpa;
|
||||
|
||||
const src_loc: Module.SrcLoc = mod.declPtr(embed_file.owner_decl).srcLoc();
|
||||
const src_loc: Module.SrcLoc = mod.declPtr(embed_file.owner_decl).srcLoc(mod);
|
||||
|
||||
const err_msg = if (embed_file.pkg.root_src_directory.path) |dir_path|
|
||||
try Module.ErrorMsg.create(
|
||||
|
||||
@ -17,7 +17,8 @@ const BigIntMutable = std.math.big.int.Mutable;
|
||||
const Limb = std.math.big.Limb;
|
||||
|
||||
const InternPool = @This();
|
||||
const DeclIndex = enum(u32) { _ };
|
||||
const DeclIndex = @import("Module.zig").Decl.Index;
|
||||
const NamespaceIndex = @import("Module.zig").Namespace.Index;
|
||||
|
||||
const KeyAdapter = struct {
|
||||
intern_pool: *const InternPool,
|
||||
@ -48,7 +49,7 @@ pub const Key = union(enum) {
|
||||
extern_func: struct {
|
||||
ty: Index,
|
||||
/// The Decl that corresponds to the function itself.
|
||||
owner_decl: DeclIndex,
|
||||
decl: DeclIndex,
|
||||
/// Library name if specified.
|
||||
/// For example `extern "c" fn write(...) usize` would have 'c' as library name.
|
||||
/// Index into the string table bytes.
|
||||
@ -62,6 +63,7 @@ pub const Key = union(enum) {
|
||||
tag: BigIntConst,
|
||||
},
|
||||
struct_type: StructType,
|
||||
opaque_type: OpaqueType,
|
||||
|
||||
union_type: struct {
|
||||
fields_len: u32,
|
||||
@ -116,6 +118,13 @@ pub const Key = union(enum) {
|
||||
// TODO move Module.Struct data to InternPool
|
||||
};
|
||||
|
||||
pub const OpaqueType = struct {
|
||||
/// The Decl that corresponds to the opaque itself.
|
||||
decl: DeclIndex,
|
||||
/// Represents the declarations inside this opaque.
|
||||
namespace: NamespaceIndex,
|
||||
};
|
||||
|
||||
pub const Int = struct {
|
||||
ty: Index,
|
||||
storage: Storage,
|
||||
@ -221,6 +230,7 @@ pub const Key = union(enum) {
|
||||
_ = union_type;
|
||||
@panic("TODO");
|
||||
},
|
||||
.opaque_type => |opaque_type| std.hash.autoHash(hasher, opaque_type.decl),
|
||||
}
|
||||
}
|
||||
|
||||
@ -338,6 +348,11 @@ pub const Key = union(enum) {
|
||||
_ = b_info;
|
||||
@panic("TODO");
|
||||
},
|
||||
|
||||
.opaque_type => |a_info| {
|
||||
const b_info = b.opaque_type;
|
||||
return a_info.decl == b_info.decl;
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@ -352,6 +367,7 @@ pub const Key = union(enum) {
|
||||
.simple_type,
|
||||
.struct_type,
|
||||
.union_type,
|
||||
.opaque_type,
|
||||
=> return .type_type,
|
||||
|
||||
inline .ptr,
|
||||
@ -770,10 +786,13 @@ pub const Tag = enum(u8) {
|
||||
/// are auto-numbered, and there are no declarations.
|
||||
/// data is payload index to `EnumSimple`.
|
||||
type_enum_simple,
|
||||
|
||||
/// A type that can be represented with only an enum tag.
|
||||
/// data is SimpleType enum value.
|
||||
simple_type,
|
||||
/// An opaque type.
|
||||
/// data is index of Key.OpaqueType in extra.
|
||||
type_opaque,
|
||||
|
||||
/// A value that can be represented with only an enum tag.
|
||||
/// data is SimpleValue enum value.
|
||||
simple_value,
|
||||
@ -986,7 +1005,7 @@ pub const ErrorUnion = struct {
|
||||
/// 0. field name: null-terminated string index for each fields_len; declaration order
|
||||
pub const EnumSimple = struct {
|
||||
/// The Decl that corresponds to the enum itself.
|
||||
owner_decl: DeclIndex,
|
||||
decl: DeclIndex,
|
||||
/// An integer type which is used for the numerical value of the enum. This
|
||||
/// is inferred by Zig to be the smallest power of two unsigned int that
|
||||
/// fits the number of fields. It is stored here to avoid unnecessary
|
||||
@ -1146,6 +1165,9 @@ pub fn indexToKey(ip: InternPool, index: Index) Key {
|
||||
|
||||
.type_error_union => @panic("TODO"),
|
||||
.type_enum_simple => @panic("TODO"),
|
||||
|
||||
.type_opaque => .{ .opaque_type = ip.extraData(Key.OpaqueType, data) },
|
||||
|
||||
.simple_internal => switch (@intToEnum(SimpleInternal, data)) {
|
||||
.type_empty_struct => .{ .struct_type = .{
|
||||
.fields_len = 0,
|
||||
@ -1335,6 +1357,29 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
|
||||
.data = @enumToInt(simple_value),
|
||||
});
|
||||
},
|
||||
|
||||
.struct_type => |struct_type| {
|
||||
if (struct_type.fields_len != 0) {
|
||||
@panic("TODO"); // handle structs other than empty_struct
|
||||
}
|
||||
ip.items.appendAssumeCapacity(.{
|
||||
.tag = .simple_internal,
|
||||
.data = @enumToInt(SimpleInternal.type_empty_struct),
|
||||
});
|
||||
},
|
||||
|
||||
.union_type => |union_type| {
|
||||
_ = union_type;
|
||||
@panic("TODO");
|
||||
},
|
||||
|
||||
.opaque_type => |opaque_type| {
|
||||
ip.items.appendAssumeCapacity(.{
|
||||
.tag = .type_opaque,
|
||||
.data = try ip.addExtra(gpa, opaque_type),
|
||||
});
|
||||
},
|
||||
|
||||
.extern_func => @panic("TODO"),
|
||||
|
||||
.ptr => |ptr| switch (ptr.addr) {
|
||||
@ -1504,21 +1549,6 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
|
||||
const tag: Tag = if (enum_tag.tag.positive) .enum_tag_positive else .enum_tag_negative;
|
||||
try addInt(ip, gpa, enum_tag.ty, tag, enum_tag.tag.limbs);
|
||||
},
|
||||
|
||||
.struct_type => |struct_type| {
|
||||
if (struct_type.fields_len != 0) {
|
||||
@panic("TODO"); // handle structs other than empty_struct
|
||||
}
|
||||
ip.items.appendAssumeCapacity(.{
|
||||
.tag = .simple_internal,
|
||||
.data = @enumToInt(SimpleInternal.type_empty_struct),
|
||||
});
|
||||
},
|
||||
|
||||
.union_type => |union_type| {
|
||||
_ = union_type;
|
||||
@panic("TODO");
|
||||
},
|
||||
}
|
||||
return @intToEnum(Index, ip.items.len - 1);
|
||||
}
|
||||
@ -1548,6 +1578,8 @@ fn addExtraAssumeCapacity(ip: *InternPool, extra: anytype) u32 {
|
||||
ip.extra.appendAssumeCapacity(switch (field.type) {
|
||||
u32 => @field(extra, field.name),
|
||||
Index => @enumToInt(@field(extra, field.name)),
|
||||
DeclIndex => @enumToInt(@field(extra, field.name)),
|
||||
NamespaceIndex => @enumToInt(@field(extra, field.name)),
|
||||
i32 => @bitCast(u32, @field(extra, field.name)),
|
||||
Pointer.Flags => @bitCast(u32, @field(extra, field.name)),
|
||||
Pointer.PackedOffset => @bitCast(u32, @field(extra, field.name)),
|
||||
@ -1603,6 +1635,8 @@ fn extraData(ip: InternPool, comptime T: type, index: usize) T {
|
||||
@field(result, field.name) = switch (field.type) {
|
||||
u32 => int32,
|
||||
Index => @intToEnum(Index, int32),
|
||||
DeclIndex => @intToEnum(DeclIndex, int32),
|
||||
NamespaceIndex => @intToEnum(NamespaceIndex, int32),
|
||||
i32 => @bitCast(i32, int32),
|
||||
Pointer.Flags => @bitCast(Pointer.Flags, int32),
|
||||
Pointer.PackedOffset => @bitCast(Pointer.PackedOffset, int32),
|
||||
@ -1824,6 +1858,7 @@ fn dumpFallible(ip: InternPool, arena: Allocator) anyerror!void {
|
||||
.type_optional => 0,
|
||||
.type_error_union => @sizeOf(ErrorUnion),
|
||||
.type_enum_simple => @sizeOf(EnumSimple),
|
||||
.type_opaque => @sizeOf(Key.OpaqueType),
|
||||
.simple_type => 0,
|
||||
.simple_value => 0,
|
||||
.simple_internal => 0,
|
||||
|
||||
395
src/Module.zig
395
src/Module.zig
@ -185,6 +185,11 @@ allocated_decls: std.SegmentedList(Decl, 0) = .{},
|
||||
/// When a Decl object is freed from `allocated_decls`, it is pushed into this stack.
|
||||
decls_free_list: ArrayListUnmanaged(Decl.Index) = .{},
|
||||
|
||||
/// Same pattern as with `allocated_decls`.
|
||||
allocated_namespaces: std.SegmentedList(Namespace, 0) = .{},
|
||||
/// Same pattern as with `decls_free_list`.
|
||||
namespaces_free_list: ArrayListUnmanaged(Namespace.Index) = .{},
|
||||
|
||||
global_assembly: std.AutoHashMapUnmanaged(Decl.Index, []u8) = .{},
|
||||
|
||||
reference_table: std.AutoHashMapUnmanaged(Decl.Index, struct {
|
||||
@ -363,7 +368,7 @@ pub const Export = struct {
|
||||
pub fn getSrcLoc(exp: Export, mod: *Module) SrcLoc {
|
||||
const src_decl = mod.declPtr(exp.src_decl);
|
||||
return .{
|
||||
.file_scope = src_decl.getFileScope(),
|
||||
.file_scope = src_decl.getFileScope(mod),
|
||||
.parent_decl_node = src_decl.src_node,
|
||||
.lazy = exp.src,
|
||||
};
|
||||
@ -494,7 +499,7 @@ pub const Decl = struct {
|
||||
/// Reference to externally owned memory.
|
||||
/// In the case of the Decl corresponding to a file, this is
|
||||
/// the namespace of the struct, since there is no parent.
|
||||
src_namespace: *Namespace,
|
||||
src_namespace: Namespace.Index,
|
||||
|
||||
/// The scope which lexically contains this decl. A decl must depend
|
||||
/// on its lexical parent, in order to ensure that this pointer is valid.
|
||||
@ -691,8 +696,8 @@ pub const Decl = struct {
|
||||
|
||||
/// This name is relative to the containing namespace of the decl.
|
||||
/// The memory is owned by the containing File ZIR.
|
||||
pub fn getName(decl: Decl) ?[:0]const u8 {
|
||||
const zir = decl.getFileScope().zir;
|
||||
pub fn getName(decl: Decl, mod: *Module) ?[:0]const u8 {
|
||||
const zir = decl.getFileScope(mod).zir;
|
||||
return decl.getNameZir(zir);
|
||||
}
|
||||
|
||||
@ -703,8 +708,8 @@ pub const Decl = struct {
|
||||
return zir.nullTerminatedString(name_index);
|
||||
}
|
||||
|
||||
pub fn contentsHash(decl: Decl) std.zig.SrcHash {
|
||||
const zir = decl.getFileScope().zir;
|
||||
pub fn contentsHash(decl: Decl, mod: *Module) std.zig.SrcHash {
|
||||
const zir = decl.getFileScope(mod).zir;
|
||||
return decl.contentsHashZir(zir);
|
||||
}
|
||||
|
||||
@ -715,31 +720,31 @@ pub const Decl = struct {
|
||||
return contents_hash;
|
||||
}
|
||||
|
||||
pub fn zirBlockIndex(decl: *const Decl) Zir.Inst.Index {
|
||||
pub fn zirBlockIndex(decl: *const Decl, mod: *Module) Zir.Inst.Index {
|
||||
assert(decl.zir_decl_index != 0);
|
||||
const zir = decl.getFileScope().zir;
|
||||
const zir = decl.getFileScope(mod).zir;
|
||||
return zir.extra[decl.zir_decl_index + 6];
|
||||
}
|
||||
|
||||
pub fn zirAlignRef(decl: Decl) Zir.Inst.Ref {
|
||||
pub fn zirAlignRef(decl: Decl, mod: *Module) Zir.Inst.Ref {
|
||||
if (!decl.has_align) return .none;
|
||||
assert(decl.zir_decl_index != 0);
|
||||
const zir = decl.getFileScope().zir;
|
||||
const zir = decl.getFileScope(mod).zir;
|
||||
return @intToEnum(Zir.Inst.Ref, zir.extra[decl.zir_decl_index + 8]);
|
||||
}
|
||||
|
||||
pub fn zirLinksectionRef(decl: Decl) Zir.Inst.Ref {
|
||||
pub fn zirLinksectionRef(decl: Decl, mod: *Module) Zir.Inst.Ref {
|
||||
if (!decl.has_linksection_or_addrspace) return .none;
|
||||
assert(decl.zir_decl_index != 0);
|
||||
const zir = decl.getFileScope().zir;
|
||||
const zir = decl.getFileScope(mod).zir;
|
||||
const extra_index = decl.zir_decl_index + 8 + @boolToInt(decl.has_align);
|
||||
return @intToEnum(Zir.Inst.Ref, zir.extra[extra_index]);
|
||||
}
|
||||
|
||||
pub fn zirAddrspaceRef(decl: Decl) Zir.Inst.Ref {
|
||||
pub fn zirAddrspaceRef(decl: Decl, mod: *Module) Zir.Inst.Ref {
|
||||
if (!decl.has_linksection_or_addrspace) return .none;
|
||||
assert(decl.zir_decl_index != 0);
|
||||
const zir = decl.getFileScope().zir;
|
||||
const zir = decl.getFileScope(mod).zir;
|
||||
const extra_index = decl.zir_decl_index + 8 + @boolToInt(decl.has_align) + 1;
|
||||
return @intToEnum(Zir.Inst.Ref, zir.extra[extra_index]);
|
||||
}
|
||||
@ -764,25 +769,25 @@ pub const Decl = struct {
|
||||
return LazySrcLoc.nodeOffset(decl.nodeIndexToRelative(node_index));
|
||||
}
|
||||
|
||||
pub fn srcLoc(decl: Decl) SrcLoc {
|
||||
return decl.nodeOffsetSrcLoc(0);
|
||||
pub fn srcLoc(decl: Decl, mod: *Module) SrcLoc {
|
||||
return decl.nodeOffsetSrcLoc(0, mod);
|
||||
}
|
||||
|
||||
pub fn nodeOffsetSrcLoc(decl: Decl, node_offset: i32) SrcLoc {
|
||||
pub fn nodeOffsetSrcLoc(decl: Decl, node_offset: i32, mod: *Module) SrcLoc {
|
||||
return .{
|
||||
.file_scope = decl.getFileScope(),
|
||||
.file_scope = decl.getFileScope(mod),
|
||||
.parent_decl_node = decl.src_node,
|
||||
.lazy = LazySrcLoc.nodeOffset(node_offset),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn srcToken(decl: Decl) Ast.TokenIndex {
|
||||
const tree = &decl.getFileScope().tree;
|
||||
pub fn srcToken(decl: Decl, mod: *Module) Ast.TokenIndex {
|
||||
const tree = &decl.getFileScope(mod).tree;
|
||||
return tree.firstToken(decl.src_node);
|
||||
}
|
||||
|
||||
pub fn srcByteOffset(decl: Decl) u32 {
|
||||
const tree = &decl.getFileScope().tree;
|
||||
pub fn srcByteOffset(decl: Decl, mod: *Module) u32 {
|
||||
const tree = &decl.getFileScope(mod).tree;
|
||||
return tree.tokens.items(.start)[decl.srcToken()];
|
||||
}
|
||||
|
||||
@ -791,12 +796,12 @@ pub const Decl = struct {
|
||||
if (decl.name_fully_qualified) {
|
||||
return writer.writeAll(unqualified_name);
|
||||
}
|
||||
return decl.src_namespace.renderFullyQualifiedName(mod, unqualified_name, writer);
|
||||
return mod.namespacePtr(decl.src_namespace).renderFullyQualifiedName(mod, unqualified_name, writer);
|
||||
}
|
||||
|
||||
pub fn renderFullyQualifiedDebugName(decl: Decl, mod: *Module, writer: anytype) !void {
|
||||
const unqualified_name = mem.sliceTo(decl.name, 0);
|
||||
return decl.src_namespace.renderFullyQualifiedDebugName(mod, unqualified_name, writer);
|
||||
return mod.namespacePtr(decl.src_namespace).renderFullyQualifiedDebugName(mod, unqualified_name, writer);
|
||||
}
|
||||
|
||||
pub fn getFullyQualifiedName(decl: Decl, mod: *Module) ![:0]u8 {
|
||||
@ -877,32 +882,39 @@ pub const Decl = struct {
|
||||
/// Gets the namespace that this Decl creates by being a struct, union,
|
||||
/// enum, or opaque.
|
||||
/// Only returns it if the Decl is the owner.
|
||||
pub fn getInnerNamespace(decl: *Decl) ?*Namespace {
|
||||
if (!decl.owns_tv) return null;
|
||||
const ty = (decl.val.castTag(.ty) orelse return null).data;
|
||||
switch (ty.tag()) {
|
||||
.@"struct" => {
|
||||
const struct_obj = ty.castTag(.@"struct").?.data;
|
||||
return &struct_obj.namespace;
|
||||
},
|
||||
.enum_full, .enum_nonexhaustive => {
|
||||
const enum_obj = ty.cast(Type.Payload.EnumFull).?.data;
|
||||
return &enum_obj.namespace;
|
||||
},
|
||||
.empty_struct => {
|
||||
return ty.castTag(.empty_struct).?.data;
|
||||
},
|
||||
.@"opaque" => {
|
||||
const opaque_obj = ty.cast(Type.Payload.Opaque).?.data;
|
||||
return &opaque_obj.namespace;
|
||||
},
|
||||
.@"union", .union_safety_tagged, .union_tagged => {
|
||||
const union_obj = ty.cast(Type.Payload.Union).?.data;
|
||||
return &union_obj.namespace;
|
||||
},
|
||||
pub fn getInnerNamespaceIndex(decl: *Decl, mod: *Module) Namespace.OptionalIndex {
|
||||
if (!decl.owns_tv) return .none;
|
||||
if (decl.val.ip_index == .none) {
|
||||
const ty = (decl.val.castTag(.ty) orelse return .none).data;
|
||||
switch (ty.tag()) {
|
||||
.@"struct" => {
|
||||
const struct_obj = ty.castTag(.@"struct").?.data;
|
||||
return struct_obj.namespace.toOptional();
|
||||
},
|
||||
.enum_full, .enum_nonexhaustive => {
|
||||
const enum_obj = ty.cast(Type.Payload.EnumFull).?.data;
|
||||
return enum_obj.namespace.toOptional();
|
||||
},
|
||||
.empty_struct => {
|
||||
@panic("TODO");
|
||||
},
|
||||
.@"union", .union_safety_tagged, .union_tagged => {
|
||||
const union_obj = ty.cast(Type.Payload.Union).?.data;
|
||||
return union_obj.namespace.toOptional();
|
||||
},
|
||||
|
||||
else => return null,
|
||||
else => return .none,
|
||||
}
|
||||
}
|
||||
return switch (mod.intern_pool.indexToKey(decl.val.ip_index)) {
|
||||
.opaque_type => |opaque_type| opaque_type.namespace.toOptional(),
|
||||
else => .none,
|
||||
};
|
||||
}
|
||||
|
||||
/// Same as `getInnerNamespaceIndex` but additionally obtains the pointer.
|
||||
pub fn getInnerNamespace(decl: *Decl, mod: *Module) ?*Namespace {
|
||||
return if (getInnerNamespaceIndex(decl, mod).unwrap()) |i| mod.namespacePtr(i) else null;
|
||||
}
|
||||
|
||||
pub fn dump(decl: *Decl) void {
|
||||
@ -920,8 +932,8 @@ pub const Decl = struct {
|
||||
std.debug.print("\n", .{});
|
||||
}
|
||||
|
||||
pub fn getFileScope(decl: Decl) *File {
|
||||
return decl.src_namespace.file_scope;
|
||||
pub fn getFileScope(decl: Decl, mod: *Module) *File {
|
||||
return mod.namespacePtr(decl.src_namespace).file_scope;
|
||||
}
|
||||
|
||||
pub fn removeDependant(decl: *Decl, other: Decl.Index) void {
|
||||
@ -974,7 +986,7 @@ pub const ErrorSet = struct {
|
||||
pub fn srcLoc(self: ErrorSet, mod: *Module) SrcLoc {
|
||||
const owner_decl = mod.declPtr(self.owner_decl);
|
||||
return .{
|
||||
.file_scope = owner_decl.getFileScope(),
|
||||
.file_scope = owner_decl.getFileScope(mod),
|
||||
.parent_decl_node = owner_decl.src_node,
|
||||
.lazy = LazySrcLoc.nodeOffset(0),
|
||||
};
|
||||
@ -1000,7 +1012,7 @@ pub const Struct = struct {
|
||||
/// Set of field names in declaration order.
|
||||
fields: Fields,
|
||||
/// Represents the declarations inside this struct.
|
||||
namespace: Namespace,
|
||||
namespace: Namespace.Index,
|
||||
/// The Decl that corresponds to the struct itself.
|
||||
owner_decl: Decl.Index,
|
||||
/// Index of the struct_decl ZIR instruction.
|
||||
@ -1101,7 +1113,7 @@ pub const Struct = struct {
|
||||
pub fn srcLoc(s: Struct, mod: *Module) SrcLoc {
|
||||
const owner_decl = mod.declPtr(s.owner_decl);
|
||||
return .{
|
||||
.file_scope = owner_decl.getFileScope(),
|
||||
.file_scope = owner_decl.getFileScope(mod),
|
||||
.parent_decl_node = owner_decl.src_node,
|
||||
.lazy = LazySrcLoc.nodeOffset(0),
|
||||
};
|
||||
@ -1110,7 +1122,7 @@ pub const Struct = struct {
|
||||
pub fn fieldSrcLoc(s: Struct, mod: *Module, query: FieldSrcQuery) SrcLoc {
|
||||
@setCold(true);
|
||||
const owner_decl = mod.declPtr(s.owner_decl);
|
||||
const file = owner_decl.getFileScope();
|
||||
const file = owner_decl.getFileScope(mod);
|
||||
const tree = file.getTree(mod.gpa) catch |err| {
|
||||
// In this case we emit a warning + a less precise source location.
|
||||
log.warn("unable to load {s}: {s}", .{
|
||||
@ -1224,7 +1236,7 @@ pub const EnumSimple = struct {
|
||||
pub fn srcLoc(self: EnumSimple, mod: *Module) SrcLoc {
|
||||
const owner_decl = mod.declPtr(self.owner_decl);
|
||||
return .{
|
||||
.file_scope = owner_decl.getFileScope(),
|
||||
.file_scope = owner_decl.getFileScope(mod),
|
||||
.parent_decl_node = owner_decl.src_node,
|
||||
.lazy = LazySrcLoc.nodeOffset(0),
|
||||
};
|
||||
@ -1253,7 +1265,7 @@ pub const EnumNumbered = struct {
|
||||
pub fn srcLoc(self: EnumNumbered, mod: *Module) SrcLoc {
|
||||
const owner_decl = mod.declPtr(self.owner_decl);
|
||||
return .{
|
||||
.file_scope = owner_decl.getFileScope(),
|
||||
.file_scope = owner_decl.getFileScope(mod),
|
||||
.parent_decl_node = owner_decl.src_node,
|
||||
.lazy = LazySrcLoc.nodeOffset(0),
|
||||
};
|
||||
@ -1275,7 +1287,7 @@ pub const EnumFull = struct {
|
||||
/// If this hash map is empty, it means the enum tags are auto-numbered.
|
||||
values: ValueMap,
|
||||
/// Represents the declarations inside this enum.
|
||||
namespace: Namespace,
|
||||
namespace: Namespace.Index,
|
||||
/// true if zig inferred this tag type, false if user specified it
|
||||
tag_ty_inferred: bool,
|
||||
|
||||
@ -1285,7 +1297,7 @@ pub const EnumFull = struct {
|
||||
pub fn srcLoc(self: EnumFull, mod: *Module) SrcLoc {
|
||||
const owner_decl = mod.declPtr(self.owner_decl);
|
||||
return .{
|
||||
.file_scope = owner_decl.getFileScope(),
|
||||
.file_scope = owner_decl.getFileScope(mod),
|
||||
.parent_decl_node = owner_decl.src_node,
|
||||
.lazy = LazySrcLoc.nodeOffset(0),
|
||||
};
|
||||
@ -1294,7 +1306,7 @@ pub const EnumFull = struct {
|
||||
pub fn fieldSrcLoc(e: EnumFull, mod: *Module, query: FieldSrcQuery) SrcLoc {
|
||||
@setCold(true);
|
||||
const owner_decl = mod.declPtr(e.owner_decl);
|
||||
const file = owner_decl.getFileScope();
|
||||
const file = owner_decl.getFileScope(mod);
|
||||
const tree = file.getTree(mod.gpa) catch |err| {
|
||||
// In this case we emit a warning + a less precise source location.
|
||||
log.warn("unable to load {s}: {s}", .{
|
||||
@ -1323,7 +1335,7 @@ pub const Union = struct {
|
||||
/// Set of field names in declaration order.
|
||||
fields: Fields,
|
||||
/// Represents the declarations inside this union.
|
||||
namespace: Namespace,
|
||||
namespace: Namespace.Index,
|
||||
/// The Decl that corresponds to the union itself.
|
||||
owner_decl: Decl.Index,
|
||||
/// Index of the union_decl ZIR instruction.
|
||||
@ -1371,7 +1383,7 @@ pub const Union = struct {
|
||||
pub fn srcLoc(self: Union, mod: *Module) SrcLoc {
|
||||
const owner_decl = mod.declPtr(self.owner_decl);
|
||||
return .{
|
||||
.file_scope = owner_decl.getFileScope(),
|
||||
.file_scope = owner_decl.getFileScope(mod),
|
||||
.parent_decl_node = owner_decl.src_node,
|
||||
.lazy = LazySrcLoc.nodeOffset(0),
|
||||
};
|
||||
@ -1380,7 +1392,7 @@ pub const Union = struct {
|
||||
pub fn fieldSrcLoc(u: Union, mod: *Module, query: FieldSrcQuery) SrcLoc {
|
||||
@setCold(true);
|
||||
const owner_decl = mod.declPtr(u.owner_decl);
|
||||
const file = owner_decl.getFileScope();
|
||||
const file = owner_decl.getFileScope(mod);
|
||||
const tree = file.getTree(mod.gpa) catch |err| {
|
||||
// In this case we emit a warning + a less precise source location.
|
||||
log.warn("unable to load {s}: {s}", .{
|
||||
@ -1563,26 +1575,6 @@ pub const Union = struct {
|
||||
}
|
||||
};
|
||||
|
||||
pub const Opaque = struct {
|
||||
/// The Decl that corresponds to the opaque itself.
|
||||
owner_decl: Decl.Index,
|
||||
/// Represents the declarations inside this opaque.
|
||||
namespace: Namespace,
|
||||
|
||||
pub fn srcLoc(self: Opaque, mod: *Module) SrcLoc {
|
||||
const owner_decl = mod.declPtr(self.owner_decl);
|
||||
return .{
|
||||
.file_scope = owner_decl.getFileScope(),
|
||||
.parent_decl_node = owner_decl.src_node,
|
||||
.lazy = LazySrcLoc.nodeOffset(0),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn getFullyQualifiedName(s: *Opaque, mod: *Module) ![:0]u8 {
|
||||
return mod.declPtr(s.owner_decl).getFullyQualifiedName(mod);
|
||||
}
|
||||
};
|
||||
|
||||
/// Some extern function struct memory is owned by the Decl's TypedValue.Managed
|
||||
/// arena allocator.
|
||||
pub const ExternFn = struct {
|
||||
@ -1759,7 +1751,7 @@ pub const Fn = struct {
|
||||
}
|
||||
|
||||
pub fn isAnytypeParam(func: Fn, mod: *Module, index: u32) bool {
|
||||
const file = mod.declPtr(func.owner_decl).getFileScope();
|
||||
const file = mod.declPtr(func.owner_decl).getFileScope(mod);
|
||||
|
||||
const tags = file.zir.instructions.items(.tag);
|
||||
|
||||
@ -1774,7 +1766,7 @@ pub const Fn = struct {
|
||||
}
|
||||
|
||||
pub fn getParamName(func: Fn, mod: *Module, index: u32) [:0]const u8 {
|
||||
const file = mod.declPtr(func.owner_decl).getFileScope();
|
||||
const file = mod.declPtr(func.owner_decl).getFileScope(mod);
|
||||
|
||||
const tags = file.zir.instructions.items(.tag);
|
||||
const data = file.zir.instructions.items(.data);
|
||||
@ -1797,7 +1789,7 @@ pub const Fn = struct {
|
||||
|
||||
pub fn hasInferredErrorSet(func: Fn, mod: *Module) bool {
|
||||
const owner_decl = mod.declPtr(func.owner_decl);
|
||||
const zir = owner_decl.getFileScope().zir;
|
||||
const zir = owner_decl.getFileScope(mod).zir;
|
||||
const zir_tags = zir.instructions.items(.tag);
|
||||
switch (zir_tags[func.zir_body_inst]) {
|
||||
.func => return false,
|
||||
@ -1851,7 +1843,7 @@ pub const DeclAdapter = struct {
|
||||
|
||||
/// The container that structs, enums, unions, and opaques have.
|
||||
pub const Namespace = struct {
|
||||
parent: ?*Namespace,
|
||||
parent: OptionalIndex,
|
||||
file_scope: *File,
|
||||
/// Will be a struct, enum, union, or opaque.
|
||||
ty: Type,
|
||||
@ -1869,6 +1861,28 @@ pub const Namespace = struct {
|
||||
/// Value is whether the usingnamespace decl is marked `pub`.
|
||||
usingnamespace_set: std.AutoHashMapUnmanaged(Decl.Index, bool) = .{},
|
||||
|
||||
pub const Index = enum(u32) {
|
||||
_,
|
||||
|
||||
pub fn toOptional(i: Index) OptionalIndex {
|
||||
return @intToEnum(OptionalIndex, @enumToInt(i));
|
||||
}
|
||||
};
|
||||
|
||||
pub const OptionalIndex = enum(u32) {
|
||||
none = std.math.maxInt(u32),
|
||||
_,
|
||||
|
||||
pub fn init(oi: ?Index) OptionalIndex {
|
||||
return @intToEnum(OptionalIndex, @enumToInt(oi orelse return .none));
|
||||
}
|
||||
|
||||
pub fn unwrap(oi: OptionalIndex) ?Index {
|
||||
if (oi == .none) return null;
|
||||
return @intToEnum(Index, @enumToInt(oi));
|
||||
}
|
||||
};
|
||||
|
||||
const DeclContext = struct {
|
||||
module: *Module,
|
||||
|
||||
@ -1955,10 +1969,10 @@ pub const Namespace = struct {
|
||||
name: []const u8,
|
||||
writer: anytype,
|
||||
) @TypeOf(writer).Error!void {
|
||||
if (ns.parent) |parent| {
|
||||
const decl_index = ns.getDeclIndex();
|
||||
if (ns.parent.unwrap()) |parent| {
|
||||
const decl_index = ns.getDeclIndex(mod);
|
||||
const decl = mod.declPtr(decl_index);
|
||||
try parent.renderFullyQualifiedName(mod, mem.sliceTo(decl.name, 0), writer);
|
||||
try mod.namespacePtr(parent).renderFullyQualifiedName(mod, mem.sliceTo(decl.name, 0), writer);
|
||||
} else {
|
||||
try ns.file_scope.renderFullyQualifiedName(writer);
|
||||
}
|
||||
@ -1976,10 +1990,10 @@ pub const Namespace = struct {
|
||||
writer: anytype,
|
||||
) @TypeOf(writer).Error!void {
|
||||
var separator_char: u8 = '.';
|
||||
if (ns.parent) |parent| {
|
||||
const decl_index = ns.getDeclIndex();
|
||||
if (ns.parent.unwrap()) |parent| {
|
||||
const decl_index = ns.getDeclIndex(mod);
|
||||
const decl = mod.declPtr(decl_index);
|
||||
try parent.renderFullyQualifiedDebugName(mod, mem.sliceTo(decl.name, 0), writer);
|
||||
try mod.namespacePtr(parent).renderFullyQualifiedDebugName(mod, mem.sliceTo(decl.name, 0), writer);
|
||||
} else {
|
||||
try ns.file_scope.renderFullyQualifiedDebugName(writer);
|
||||
separator_char = ':';
|
||||
@ -1990,8 +2004,8 @@ pub const Namespace = struct {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn getDeclIndex(ns: Namespace) Decl.Index {
|
||||
return ns.ty.getOwnerDecl();
|
||||
pub fn getDeclIndex(ns: Namespace, mod: *Module) Decl.Index {
|
||||
return ns.ty.getOwnerDecl(mod);
|
||||
}
|
||||
};
|
||||
|
||||
@ -3320,7 +3334,7 @@ pub const LazySrcLoc = union(enum) {
|
||||
}
|
||||
|
||||
/// Upgrade to a `SrcLoc` based on the `Decl` provided.
|
||||
pub fn toSrcLoc(lazy: LazySrcLoc, decl: *Decl) SrcLoc {
|
||||
pub fn toSrcLoc(lazy: LazySrcLoc, decl: *Decl, mod: *Module) SrcLoc {
|
||||
return switch (lazy) {
|
||||
.unneeded,
|
||||
.entire_file,
|
||||
@ -3328,7 +3342,7 @@ pub const LazySrcLoc = union(enum) {
|
||||
.token_abs,
|
||||
.node_abs,
|
||||
=> .{
|
||||
.file_scope = decl.getFileScope(),
|
||||
.file_scope = decl.getFileScope(mod),
|
||||
.parent_decl_node = 0,
|
||||
.lazy = lazy,
|
||||
},
|
||||
@ -3394,7 +3408,7 @@ pub const LazySrcLoc = union(enum) {
|
||||
.for_input,
|
||||
.for_capture_from_input,
|
||||
=> .{
|
||||
.file_scope = decl.getFileScope(),
|
||||
.file_scope = decl.getFileScope(mod),
|
||||
.parent_decl_node = decl.src_node,
|
||||
.lazy = lazy,
|
||||
},
|
||||
@ -3555,6 +3569,9 @@ pub fn deinit(mod: *Module) void {
|
||||
mod.global_assembly.deinit(gpa);
|
||||
mod.reference_table.deinit(gpa);
|
||||
|
||||
mod.namespaces_free_list.deinit(gpa);
|
||||
mod.allocated_namespaces.deinit(gpa);
|
||||
|
||||
mod.string_literal_table.deinit(gpa);
|
||||
mod.string_literal_bytes.deinit(gpa);
|
||||
|
||||
@ -3575,8 +3592,9 @@ pub fn destroyDecl(mod: *Module, decl_index: Decl.Index) void {
|
||||
gpa.free(kv.value);
|
||||
}
|
||||
if (decl.has_tv) {
|
||||
if (decl.getInnerNamespace()) |namespace| {
|
||||
namespace.destroyDecls(mod);
|
||||
if (decl.getInnerNamespaceIndex(mod).unwrap()) |i| {
|
||||
mod.namespacePtr(i).destroyDecls(mod);
|
||||
mod.destroyNamespace(i);
|
||||
}
|
||||
}
|
||||
decl.clearValues(mod);
|
||||
@ -3596,16 +3614,21 @@ pub fn destroyDecl(mod: *Module, decl_index: Decl.Index) void {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn declPtr(mod: *Module, decl_index: Decl.Index) *Decl {
|
||||
return mod.allocated_decls.at(@enumToInt(decl_index));
|
||||
pub fn declPtr(mod: *Module, index: Decl.Index) *Decl {
|
||||
return mod.allocated_decls.at(@enumToInt(index));
|
||||
}
|
||||
|
||||
pub fn namespacePtr(mod: *Module, index: Namespace.Index) *Namespace {
|
||||
return mod.allocated_namespaces.at(@enumToInt(index));
|
||||
}
|
||||
|
||||
/// Returns true if and only if the Decl is the top level struct associated with a File.
|
||||
pub fn declIsRoot(mod: *Module, decl_index: Decl.Index) bool {
|
||||
const decl = mod.declPtr(decl_index);
|
||||
if (decl.src_namespace.parent != null)
|
||||
const namespace = mod.namespacePtr(decl.src_namespace);
|
||||
if (namespace.parent != .none)
|
||||
return false;
|
||||
return decl_index == decl.src_namespace.getDeclIndex();
|
||||
return decl_index == namespace.getDeclIndex(mod);
|
||||
}
|
||||
|
||||
fn freeExportList(gpa: Allocator, export_list: *ArrayListUnmanaged(*Export)) void {
|
||||
@ -4076,7 +4099,7 @@ fn updateZirRefs(mod: *Module, file: *File, old_zir: Zir) !void {
|
||||
};
|
||||
}
|
||||
|
||||
if (decl.getInnerNamespace()) |namespace| {
|
||||
if (decl.getInnerNamespace(mod)) |namespace| {
|
||||
for (namespace.decls.keys()) |sub_decl| {
|
||||
try decl_stack.append(gpa, sub_decl);
|
||||
}
|
||||
@ -4306,7 +4329,7 @@ pub fn ensureDeclAnalyzed(mod: *Module, decl_index: Decl.Index) SemaError!void {
|
||||
try mod.failed_decls.ensureUnusedCapacity(mod.gpa, 1);
|
||||
mod.failed_decls.putAssumeCapacityNoClobber(decl_index, try ErrorMsg.create(
|
||||
mod.gpa,
|
||||
decl.srcLoc(),
|
||||
decl.srcLoc(mod),
|
||||
"unable to analyze: {s}",
|
||||
.{@errorName(e)},
|
||||
));
|
||||
@ -4437,7 +4460,7 @@ pub fn ensureFuncBodyAnalyzed(mod: *Module, func: *Fn) SemaError!void {
|
||||
decl_index,
|
||||
try Module.ErrorMsg.create(
|
||||
gpa,
|
||||
decl.srcLoc(),
|
||||
decl.srcLoc(mod),
|
||||
"invalid liveness: {s}",
|
||||
.{@errorName(err)},
|
||||
),
|
||||
@ -4460,7 +4483,7 @@ pub fn ensureFuncBodyAnalyzed(mod: *Module, func: *Fn) SemaError!void {
|
||||
try mod.failed_decls.ensureUnusedCapacity(gpa, 1);
|
||||
mod.failed_decls.putAssumeCapacityNoClobber(decl_index, try Module.ErrorMsg.create(
|
||||
gpa,
|
||||
decl.srcLoc(),
|
||||
decl.srcLoc(mod),
|
||||
"unable to codegen: {s}",
|
||||
.{@errorName(err)},
|
||||
));
|
||||
@ -4586,13 +4609,13 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {
|
||||
.status = .none,
|
||||
.known_non_opv = undefined,
|
||||
.is_tuple = undefined, // set below
|
||||
.namespace = .{
|
||||
.parent = null,
|
||||
.namespace = try mod.createNamespace(.{
|
||||
.parent = .none,
|
||||
.ty = struct_ty,
|
||||
.file_scope = file,
|
||||
},
|
||||
}),
|
||||
};
|
||||
const new_decl_index = try mod.allocateNewDecl(&struct_obj.namespace, 0, null);
|
||||
const new_decl_index = try mod.allocateNewDecl(struct_obj.namespace, 0, null);
|
||||
const new_decl = mod.declPtr(new_decl_index);
|
||||
file.root_decl = new_decl_index.toOptional();
|
||||
struct_obj.owner_decl = new_decl_index;
|
||||
@ -4688,12 +4711,12 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
|
||||
|
||||
const decl = mod.declPtr(decl_index);
|
||||
|
||||
if (decl.getFileScope().status != .success_zir) {
|
||||
if (decl.getFileScope(mod).status != .success_zir) {
|
||||
return error.AnalysisFail;
|
||||
}
|
||||
|
||||
const gpa = mod.gpa;
|
||||
const zir = decl.getFileScope().zir;
|
||||
const zir = decl.getFileScope(mod).zir;
|
||||
const zir_datas = zir.instructions.items(.data);
|
||||
|
||||
decl.analysis = .in_progress;
|
||||
@ -4767,7 +4790,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
|
||||
block_scope.params.deinit(gpa);
|
||||
}
|
||||
|
||||
const zir_block_index = decl.zirBlockIndex();
|
||||
const zir_block_index = decl.zirBlockIndex(mod);
|
||||
const inst_data = zir_datas[zir_block_index].pl_node;
|
||||
const extra = zir.extraData(Zir.Inst.Block, inst_data.payload_index);
|
||||
const body = zir.extra[extra.end..][0..extra.data.body_len];
|
||||
@ -4792,7 +4815,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
|
||||
});
|
||||
}
|
||||
const ty = try decl_tv.val.toType().copy(decl_arena_allocator);
|
||||
if (ty.getNamespace() == null) {
|
||||
if (ty.getNamespace(mod) == null) {
|
||||
return sema.fail(&block_scope, ty_src, "type {} has no namespace", .{ty.fmt(mod)});
|
||||
}
|
||||
|
||||
@ -4895,12 +4918,12 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
|
||||
decl.ty = try decl_tv.ty.copy(decl_arena_allocator);
|
||||
decl.val = try decl_tv.val.copy(decl_arena_allocator);
|
||||
decl.@"align" = blk: {
|
||||
const align_ref = decl.zirAlignRef();
|
||||
const align_ref = decl.zirAlignRef(mod);
|
||||
if (align_ref == .none) break :blk 0;
|
||||
break :blk try sema.resolveAlign(&block_scope, align_src, align_ref);
|
||||
};
|
||||
decl.@"linksection" = blk: {
|
||||
const linksection_ref = decl.zirLinksectionRef();
|
||||
const linksection_ref = decl.zirLinksectionRef(mod);
|
||||
if (linksection_ref == .none) break :blk null;
|
||||
const bytes = try sema.resolveConstString(&block_scope, section_src, linksection_ref, "linksection must be comptime-known");
|
||||
if (mem.indexOfScalar(u8, bytes, 0) != null) {
|
||||
@ -4921,7 +4944,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
|
||||
};
|
||||
|
||||
const target = sema.mod.getTarget();
|
||||
break :blk switch (decl.zirAddrspaceRef()) {
|
||||
break :blk switch (decl.zirAddrspaceRef(mod)) {
|
||||
.none => switch (addrspace_ctx) {
|
||||
.function => target_util.defaultAddressSpace(target, .function),
|
||||
.variable => target_util.defaultAddressSpace(target, .global_mutable),
|
||||
@ -5273,7 +5296,7 @@ pub fn detectEmbedFileUpdate(mod: *Module, embed_file: *EmbedFile) !void {
|
||||
|
||||
pub fn scanNamespace(
|
||||
mod: *Module,
|
||||
namespace: *Namespace,
|
||||
namespace_index: Namespace.Index,
|
||||
extra_start: usize,
|
||||
decls_len: u32,
|
||||
parent_decl: *Decl,
|
||||
@ -5282,6 +5305,7 @@ pub fn scanNamespace(
|
||||
defer tracy.end();
|
||||
|
||||
const gpa = mod.gpa;
|
||||
const namespace = mod.namespacePtr(namespace_index);
|
||||
const zir = namespace.file_scope.zir;
|
||||
|
||||
try mod.comp.work_queue.ensureUnusedCapacity(decls_len);
|
||||
@ -5294,7 +5318,7 @@ pub fn scanNamespace(
|
||||
var decl_i: u32 = 0;
|
||||
var scan_decl_iter: ScanDeclIter = .{
|
||||
.module = mod,
|
||||
.namespace = namespace,
|
||||
.namespace_index = namespace_index,
|
||||
.parent_decl = parent_decl,
|
||||
};
|
||||
while (decl_i < decls_len) : (decl_i += 1) {
|
||||
@ -5317,7 +5341,7 @@ pub fn scanNamespace(
|
||||
|
||||
const ScanDeclIter = struct {
|
||||
module: *Module,
|
||||
namespace: *Namespace,
|
||||
namespace_index: Namespace.Index,
|
||||
parent_decl: *Decl,
|
||||
usingnamespace_index: usize = 0,
|
||||
comptime_index: usize = 0,
|
||||
@ -5329,7 +5353,8 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err
|
||||
defer tracy.end();
|
||||
|
||||
const mod = iter.module;
|
||||
const namespace = iter.namespace;
|
||||
const namespace_index = iter.namespace_index;
|
||||
const namespace = mod.namespacePtr(namespace_index);
|
||||
const gpa = mod.gpa;
|
||||
const zir = namespace.file_scope.zir;
|
||||
|
||||
@ -5404,7 +5429,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err
|
||||
);
|
||||
const comp = mod.comp;
|
||||
if (!gop.found_existing) {
|
||||
const new_decl_index = try mod.allocateNewDecl(namespace, decl_node, iter.parent_decl.src_scope);
|
||||
const new_decl_index = try mod.allocateNewDecl(namespace_index, decl_node, iter.parent_decl.src_scope);
|
||||
const new_decl = mod.declPtr(new_decl_index);
|
||||
new_decl.kind = kind;
|
||||
new_decl.name = decl_name;
|
||||
@ -5456,7 +5481,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err
|
||||
const decl = mod.declPtr(decl_index);
|
||||
if (kind == .@"test") {
|
||||
const src_loc = SrcLoc{
|
||||
.file_scope = decl.getFileScope(),
|
||||
.file_scope = decl.getFileScope(mod),
|
||||
.parent_decl_node = decl.src_node,
|
||||
.lazy = .{ .token_offset = 1 },
|
||||
};
|
||||
@ -5564,7 +5589,7 @@ pub fn clearDecl(
|
||||
if (decl.ty.isFnOrHasRuntimeBits(mod)) {
|
||||
mod.comp.bin_file.freeDecl(decl_index);
|
||||
}
|
||||
if (decl.getInnerNamespace()) |namespace| {
|
||||
if (decl.getInnerNamespace(mod)) |namespace| {
|
||||
try namespace.deleteAllDecls(mod, outdated_decls);
|
||||
}
|
||||
}
|
||||
@ -5584,7 +5609,7 @@ pub fn deleteUnusedDecl(mod: *Module, decl_index: Decl.Index) void {
|
||||
log.debug("deleteUnusedDecl {d} ({s})", .{ decl_index, decl.name });
|
||||
|
||||
assert(!mod.declIsRoot(decl_index));
|
||||
assert(decl.src_namespace.anon_decls.swapRemove(decl_index));
|
||||
assert(mod.namespacePtr(decl.src_namespace).anon_decls.swapRemove(decl_index));
|
||||
|
||||
const dependants = decl.dependants.keys();
|
||||
for (dependants) |dep| {
|
||||
@ -5612,7 +5637,7 @@ pub fn abortAnonDecl(mod: *Module, decl_index: Decl.Index) void {
|
||||
log.debug("abortAnonDecl {*} ({s})", .{ decl, decl.name });
|
||||
|
||||
assert(!mod.declIsRoot(decl_index));
|
||||
assert(decl.src_namespace.anon_decls.swapRemove(decl_index));
|
||||
assert(mod.namespacePtr(decl.src_namespace).anon_decls.swapRemove(decl_index));
|
||||
|
||||
// An aborted decl must not have dependants -- they must have
|
||||
// been aborted first and removed from this list.
|
||||
@ -5689,7 +5714,7 @@ pub fn analyzeFnBody(mod: *Module, func: *Fn, arena: Allocator) SemaError!Air {
|
||||
.gpa = gpa,
|
||||
.arena = arena,
|
||||
.perm_arena = decl_arena_allocator,
|
||||
.code = decl.getFileScope().zir,
|
||||
.code = decl.getFileScope(mod).zir,
|
||||
.owner_decl = decl,
|
||||
.owner_decl_index = decl_index,
|
||||
.func = func,
|
||||
@ -5920,9 +5945,34 @@ fn markOutdatedDecl(mod: *Module, decl_index: Decl.Index) !void {
|
||||
decl.analysis = .outdated;
|
||||
}
|
||||
|
||||
pub const CreateNamespaceOptions = struct {
|
||||
parent: Namespace.OptionalIndex,
|
||||
file_scope: *File,
|
||||
ty: Type,
|
||||
};
|
||||
|
||||
pub fn createNamespace(mod: *Module, options: CreateNamespaceOptions) !Namespace.Index {
|
||||
if (mod.namespaces_free_list.popOrNull()) |index| return index;
|
||||
const ptr = try mod.allocated_namespaces.addOne(mod.gpa);
|
||||
ptr.* = .{
|
||||
.parent = options.parent,
|
||||
.file_scope = options.file_scope,
|
||||
.ty = options.ty,
|
||||
};
|
||||
return @intToEnum(Namespace.Index, mod.allocated_namespaces.len - 1);
|
||||
}
|
||||
|
||||
pub fn destroyNamespace(mod: *Module, index: Namespace.Index) void {
|
||||
mod.namespacePtr(index).* = undefined;
|
||||
mod.namespaces_free_list.append(mod.gpa, index) catch {
|
||||
// In order to keep `destroyNamespace` a non-fallible function, we ignore memory
|
||||
// allocation failures here, instead leaking the Namespace until garbage collection.
|
||||
};
|
||||
}
|
||||
|
||||
pub fn allocateNewDecl(
|
||||
mod: *Module,
|
||||
namespace: *Namespace,
|
||||
namespace: Namespace.Index,
|
||||
src_node: Ast.Node.Index,
|
||||
src_scope: ?*CaptureScope,
|
||||
) !Decl.Index {
|
||||
@ -6004,7 +6054,7 @@ pub fn createAnonymousDecl(mod: *Module, block: *Sema.Block, typed_value: TypedV
|
||||
pub fn createAnonymousDeclFromDecl(
|
||||
mod: *Module,
|
||||
src_decl: *Decl,
|
||||
namespace: *Namespace,
|
||||
namespace: Namespace.Index,
|
||||
src_scope: ?*CaptureScope,
|
||||
tv: TypedValue,
|
||||
) !Decl.Index {
|
||||
@ -6022,7 +6072,7 @@ pub fn initNewAnonDecl(
|
||||
mod: *Module,
|
||||
new_decl_index: Decl.Index,
|
||||
src_line: u32,
|
||||
namespace: *Namespace,
|
||||
namespace: Namespace.Index,
|
||||
typed_value: TypedValue,
|
||||
name: [:0]u8,
|
||||
) !void {
|
||||
@ -6040,7 +6090,7 @@ pub fn initNewAnonDecl(
|
||||
new_decl.analysis = .complete;
|
||||
new_decl.generation = mod.generation;
|
||||
|
||||
try namespace.anon_decls.putNoClobber(mod.gpa, new_decl_index, {});
|
||||
try mod.namespacePtr(namespace).anon_decls.putNoClobber(mod.gpa, new_decl_index, {});
|
||||
|
||||
// The Decl starts off with alive=false and the codegen backend will set alive=true
|
||||
// if the Decl is referenced by an instruction or another constant. Otherwise,
|
||||
@ -6110,16 +6160,17 @@ pub const SwitchProngSrc = union(enum) {
|
||||
/// the LazySrcLoc in order to emit a compile error.
|
||||
pub fn resolve(
|
||||
prong_src: SwitchProngSrc,
|
||||
gpa: Allocator,
|
||||
mod: *Module,
|
||||
decl: *Decl,
|
||||
switch_node_offset: i32,
|
||||
range_expand: RangeExpand,
|
||||
) LazySrcLoc {
|
||||
@setCold(true);
|
||||
const tree = decl.getFileScope().getTree(gpa) catch |err| {
|
||||
const gpa = mod.gpa;
|
||||
const tree = decl.getFileScope(mod).getTree(gpa) catch |err| {
|
||||
// In this case we emit a warning + a less precise source location.
|
||||
log.warn("unable to load {s}: {s}", .{
|
||||
decl.getFileScope().sub_file_path, @errorName(err),
|
||||
decl.getFileScope(mod).sub_file_path, @errorName(err),
|
||||
});
|
||||
return LazySrcLoc.nodeOffset(0);
|
||||
};
|
||||
@ -6203,11 +6254,12 @@ pub const PeerTypeCandidateSrc = union(enum) {
|
||||
|
||||
pub fn resolve(
|
||||
self: PeerTypeCandidateSrc,
|
||||
gpa: Allocator,
|
||||
mod: *Module,
|
||||
decl: *Decl,
|
||||
candidate_i: usize,
|
||||
) ?LazySrcLoc {
|
||||
@setCold(true);
|
||||
const gpa = mod.gpa;
|
||||
|
||||
switch (self) {
|
||||
.none => {
|
||||
@ -6229,10 +6281,10 @@ pub const PeerTypeCandidateSrc = union(enum) {
|
||||
else => {},
|
||||
}
|
||||
|
||||
const tree = decl.getFileScope().getTree(gpa) catch |err| {
|
||||
const tree = decl.getFileScope(mod).getTree(gpa) catch |err| {
|
||||
// In this case we emit a warning + a less precise source location.
|
||||
log.warn("unable to load {s}: {s}", .{
|
||||
decl.getFileScope().sub_file_path, @errorName(err),
|
||||
decl.getFileScope(mod).sub_file_path, @errorName(err),
|
||||
});
|
||||
return LazySrcLoc.nodeOffset(0);
|
||||
};
|
||||
@ -6291,15 +6343,16 @@ fn queryFieldSrc(
|
||||
|
||||
pub fn paramSrc(
|
||||
func_node_offset: i32,
|
||||
gpa: Allocator,
|
||||
mod: *Module,
|
||||
decl: *Decl,
|
||||
param_i: usize,
|
||||
) LazySrcLoc {
|
||||
@setCold(true);
|
||||
const tree = decl.getFileScope().getTree(gpa) catch |err| {
|
||||
const gpa = mod.gpa;
|
||||
const tree = decl.getFileScope(mod).getTree(gpa) catch |err| {
|
||||
// In this case we emit a warning + a less precise source location.
|
||||
log.warn("unable to load {s}: {s}", .{
|
||||
decl.getFileScope().sub_file_path, @errorName(err),
|
||||
decl.getFileScope(mod).sub_file_path, @errorName(err),
|
||||
});
|
||||
return LazySrcLoc.nodeOffset(0);
|
||||
};
|
||||
@ -6321,19 +6374,20 @@ pub fn paramSrc(
|
||||
}
|
||||
|
||||
pub fn argSrc(
|
||||
mod: *Module,
|
||||
call_node_offset: i32,
|
||||
gpa: Allocator,
|
||||
decl: *Decl,
|
||||
start_arg_i: usize,
|
||||
bound_arg_src: ?LazySrcLoc,
|
||||
) LazySrcLoc {
|
||||
@setCold(true);
|
||||
const gpa = mod.gpa;
|
||||
if (start_arg_i == 0 and bound_arg_src != null) return bound_arg_src.?;
|
||||
const arg_i = start_arg_i - @boolToInt(bound_arg_src != null);
|
||||
@setCold(true);
|
||||
const tree = decl.getFileScope().getTree(gpa) catch |err| {
|
||||
const tree = decl.getFileScope(mod).getTree(gpa) catch |err| {
|
||||
// In this case we emit a warning + a less precise source location.
|
||||
log.warn("unable to load {s}: {s}", .{
|
||||
decl.getFileScope().sub_file_path, @errorName(err),
|
||||
decl.getFileScope(mod).sub_file_path, @errorName(err),
|
||||
});
|
||||
return LazySrcLoc.nodeOffset(0);
|
||||
};
|
||||
@ -6347,7 +6401,7 @@ pub fn argSrc(
|
||||
const node_datas = tree.nodes.items(.data);
|
||||
const call_args_node = tree.extra_data[node_datas[node].rhs - 1];
|
||||
const call_args_offset = decl.nodeIndexToRelative(call_args_node);
|
||||
return initSrc(call_args_offset, gpa, decl, arg_i);
|
||||
return mod.initSrc(call_args_offset, decl, arg_i);
|
||||
},
|
||||
else => unreachable,
|
||||
};
|
||||
@ -6355,16 +6409,17 @@ pub fn argSrc(
|
||||
}
|
||||
|
||||
pub fn initSrc(
|
||||
mod: *Module,
|
||||
init_node_offset: i32,
|
||||
gpa: Allocator,
|
||||
decl: *Decl,
|
||||
init_index: usize,
|
||||
) LazySrcLoc {
|
||||
@setCold(true);
|
||||
const tree = decl.getFileScope().getTree(gpa) catch |err| {
|
||||
const gpa = mod.gpa;
|
||||
const tree = decl.getFileScope(mod).getTree(gpa) catch |err| {
|
||||
// In this case we emit a warning + a less precise source location.
|
||||
log.warn("unable to load {s}: {s}", .{
|
||||
decl.getFileScope().sub_file_path, @errorName(err),
|
||||
decl.getFileScope(mod).sub_file_path, @errorName(err),
|
||||
});
|
||||
return LazySrcLoc.nodeOffset(0);
|
||||
};
|
||||
@ -6400,12 +6455,13 @@ pub fn initSrc(
|
||||
}
|
||||
}
|
||||
|
||||
pub fn optionsSrc(gpa: Allocator, decl: *Decl, base_src: LazySrcLoc, wanted: []const u8) LazySrcLoc {
|
||||
pub fn optionsSrc(mod: *Module, decl: *Decl, base_src: LazySrcLoc, wanted: []const u8) LazySrcLoc {
|
||||
@setCold(true);
|
||||
const tree = decl.getFileScope().getTree(gpa) catch |err| {
|
||||
const gpa = mod.gpa;
|
||||
const tree = decl.getFileScope(mod).getTree(gpa) catch |err| {
|
||||
// In this case we emit a warning + a less precise source location.
|
||||
log.warn("unable to load {s}: {s}", .{
|
||||
decl.getFileScope().sub_file_path, @errorName(err),
|
||||
decl.getFileScope(mod).sub_file_path, @errorName(err),
|
||||
});
|
||||
return LazySrcLoc.nodeOffset(0);
|
||||
};
|
||||
@ -6471,7 +6527,10 @@ pub fn processOutdatedAndDeletedDecls(mod: *Module) !void {
|
||||
|
||||
// Remove from the namespace it resides in, preserving declaration order.
|
||||
assert(decl.zir_decl_index != 0);
|
||||
_ = decl.src_namespace.decls.orderedRemoveAdapted(@as([]const u8, mem.sliceTo(decl.name, 0)), DeclAdapter{ .mod = mod });
|
||||
_ = mod.namespacePtr(decl.src_namespace).decls.orderedRemoveAdapted(
|
||||
@as([]const u8, mem.sliceTo(decl.name, 0)),
|
||||
DeclAdapter{ .mod = mod },
|
||||
);
|
||||
|
||||
try mod.clearDecl(decl_index, &outdated_decls);
|
||||
mod.destroyDecl(decl_index);
|
||||
@ -6541,8 +6600,11 @@ pub fn populateTestFunctions(
|
||||
const builtin_pkg = mod.main_pkg.table.get("builtin").?;
|
||||
const builtin_file = (mod.importPkg(builtin_pkg) catch unreachable).file;
|
||||
const root_decl = mod.declPtr(builtin_file.root_decl.unwrap().?);
|
||||
const builtin_namespace = root_decl.src_namespace;
|
||||
const decl_index = builtin_namespace.decls.getKeyAdapted(@as([]const u8, "test_functions"), DeclAdapter{ .mod = mod }).?;
|
||||
const builtin_namespace = mod.namespacePtr(root_decl.src_namespace);
|
||||
const decl_index = builtin_namespace.decls.getKeyAdapted(
|
||||
@as([]const u8, "test_functions"),
|
||||
DeclAdapter{ .mod = mod },
|
||||
).?;
|
||||
{
|
||||
// We have to call `ensureDeclAnalyzed` here in case `builtin.test_functions`
|
||||
// was not referenced by start code.
|
||||
@ -6673,7 +6735,7 @@ pub fn linkerUpdateDecl(mod: *Module, decl_index: Decl.Index) !void {
|
||||
try mod.failed_decls.ensureUnusedCapacity(gpa, 1);
|
||||
mod.failed_decls.putAssumeCapacityNoClobber(decl_index, try ErrorMsg.create(
|
||||
gpa,
|
||||
decl.srcLoc(),
|
||||
decl.srcLoc(mod),
|
||||
"unable to codegen: {s}",
|
||||
.{@errorName(err)},
|
||||
));
|
||||
@ -7138,3 +7200,24 @@ pub fn atomicPtrAlignment(
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
pub fn opaqueSrcLoc(mod: *Module, opaque_type: InternPool.Key.OpaqueType) SrcLoc {
|
||||
const owner_decl = mod.declPtr(opaque_type.decl);
|
||||
return .{
|
||||
.file_scope = owner_decl.getFileScope(mod),
|
||||
.parent_decl_node = owner_decl.src_node,
|
||||
.lazy = LazySrcLoc.nodeOffset(0),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn opaqueFullyQualifiedName(mod: *Module, opaque_type: InternPool.Key.OpaqueType) ![:0]u8 {
|
||||
return mod.declPtr(opaque_type.decl).getFullyQualifiedName(mod);
|
||||
}
|
||||
|
||||
pub fn declFileScope(mod: *Module, decl_index: Decl.Index) *File {
|
||||
return mod.declPtr(decl_index).getFileScope(mod);
|
||||
}
|
||||
|
||||
pub fn namespaceDeclIndex(mod: *Module, namespace_index: Namespace.Index) Decl.Index {
|
||||
return mod.namespacePtr(namespace_index).getDeclIndex(mod);
|
||||
}
|
||||
|
||||
637
src/Sema.zig
637
src/Sema.zig
File diff suppressed because it is too large
Load Diff
@ -764,8 +764,9 @@ pub fn deinit(func: *CodeGen) void {
|
||||
|
||||
/// Sets `err_msg` on `CodeGen` and returns `error.CodegenFail` which is caught in link/Wasm.zig
|
||||
fn fail(func: *CodeGen, comptime fmt: []const u8, args: anytype) InnerError {
|
||||
const mod = func.bin_file.base.options.module.?;
|
||||
const src = LazySrcLoc.nodeOffset(0);
|
||||
const src_loc = src.toSrcLoc(func.decl);
|
||||
const src_loc = src.toSrcLoc(func.decl, mod);
|
||||
func.err_msg = try Module.ErrorMsg.create(func.gpa, src_loc, fmt, args);
|
||||
return error.CodegenFail;
|
||||
}
|
||||
@ -6799,7 +6800,7 @@ fn airTagName(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
|
||||
|
||||
fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {
|
||||
const mod = func.bin_file.base.options.module.?;
|
||||
const enum_decl_index = enum_ty.getOwnerDecl();
|
||||
const enum_decl_index = enum_ty.getOwnerDecl(mod);
|
||||
|
||||
var arena_allocator = std.heap.ArenaAllocator.init(func.gpa);
|
||||
defer arena_allocator.deinit();
|
||||
|
||||
@ -254,7 +254,7 @@ fn fail(emit: *Emit, comptime format: []const u8, args: anytype) InnerError {
|
||||
@setCold(true);
|
||||
std.debug.assert(emit.error_msg == null);
|
||||
const mod = emit.bin_file.base.options.module.?;
|
||||
emit.error_msg = try Module.ErrorMsg.create(emit.bin_file.base.allocator, mod.declPtr(emit.decl_index).srcLoc(), format, args);
|
||||
emit.error_msg = try Module.ErrorMsg.create(emit.bin_file.base.allocator, mod.declPtr(emit.decl_index).srcLoc(mod), format, args);
|
||||
return error.EmitFail;
|
||||
}
|
||||
|
||||
|
||||
@ -112,10 +112,10 @@ const Owner = union(enum) {
|
||||
mod_fn: *const Module.Fn,
|
||||
lazy_sym: link.File.LazySymbol,
|
||||
|
||||
fn getDecl(owner: Owner) Module.Decl.Index {
|
||||
fn getDecl(owner: Owner, mod: *Module) Module.Decl.Index {
|
||||
return switch (owner) {
|
||||
.mod_fn => |mod_fn| mod_fn.owner_decl,
|
||||
.lazy_sym => |lazy_sym| lazy_sym.ty.getOwnerDecl(),
|
||||
.lazy_sym => |lazy_sym| lazy_sym.ty.getOwnerDecl(mod),
|
||||
};
|
||||
}
|
||||
|
||||
@ -7926,6 +7926,7 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
|
||||
}
|
||||
|
||||
fn genArgDbgInfo(self: Self, ty: Type, name: [:0]const u8, mcv: MCValue) !void {
|
||||
const mod = self.bin_file.options.module.?;
|
||||
switch (self.debug_output) {
|
||||
.dwarf => |dw| {
|
||||
const loc: link.File.Dwarf.DeclState.DbgInfoLoc = switch (mcv) {
|
||||
@ -7944,7 +7945,7 @@ fn genArgDbgInfo(self: Self, ty: Type, name: [:0]const u8, mcv: MCValue) !void {
|
||||
// TODO: this might need adjusting like the linkers do.
|
||||
// Instead of flattening the owner and passing Decl.Index here we may
|
||||
// want to special case LazySymbol in DWARF linker too.
|
||||
try dw.genArgDbgInfo(name, ty, self.owner.getDecl(), loc);
|
||||
try dw.genArgDbgInfo(name, ty, self.owner.getDecl(mod), loc);
|
||||
},
|
||||
.plan9 => {},
|
||||
.none => {},
|
||||
@ -7958,6 +7959,7 @@ fn genVarDbgInfo(
|
||||
mcv: MCValue,
|
||||
name: [:0]const u8,
|
||||
) !void {
|
||||
const mod = self.bin_file.options.module.?;
|
||||
const is_ptr = switch (tag) {
|
||||
.dbg_var_ptr => true,
|
||||
.dbg_var_val => false,
|
||||
@ -7988,7 +7990,7 @@ fn genVarDbgInfo(
|
||||
// TODO: this might need adjusting like the linkers do.
|
||||
// Instead of flattening the owner and passing Decl.Index here we may
|
||||
// want to special case LazySymbol in DWARF linker too.
|
||||
try dw.genVarDbgInfo(name, ty, self.owner.getDecl(), is_ptr, loc);
|
||||
try dw.genVarDbgInfo(name, ty, self.owner.getDecl(mod), is_ptr, loc);
|
||||
},
|
||||
.plan9 => {},
|
||||
.none => {},
|
||||
@ -10936,7 +10938,7 @@ fn airTagName(self: *Self, inst: Air.Inst.Index) !void {
|
||||
try self.genLazySymbolRef(
|
||||
.call,
|
||||
.rax,
|
||||
link.File.LazySymbol.initDecl(.code, enum_ty.getOwnerDecl(), mod),
|
||||
link.File.LazySymbol.initDecl(.code, enum_ty.getOwnerDecl(mod), mod),
|
||||
);
|
||||
|
||||
return self.finishAir(inst, dst_mcv, .{ un_op, .none, .none });
|
||||
@ -11651,7 +11653,8 @@ fn limitImmediateType(self: *Self, operand: Air.Inst.Ref, comptime T: type) !MCV
|
||||
}
|
||||
|
||||
fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue {
|
||||
return switch (try codegen.genTypedValue(self.bin_file, self.src_loc, arg_tv, self.owner.getDecl())) {
|
||||
const mod = self.bin_file.options.module.?;
|
||||
return switch (try codegen.genTypedValue(self.bin_file, self.src_loc, arg_tv, self.owner.getDecl(mod))) {
|
||||
.mcv => |mcv| switch (mcv) {
|
||||
.none => .none,
|
||||
.undef => .undef,
|
||||
|
||||
@ -524,8 +524,9 @@ pub const DeclGen = struct {
|
||||
|
||||
fn fail(dg: *DeclGen, comptime format: []const u8, args: anytype) error{ AnalysisFail, OutOfMemory } {
|
||||
@setCold(true);
|
||||
const mod = dg.module;
|
||||
const src = LazySrcLoc.nodeOffset(0);
|
||||
const src_loc = src.toSrcLoc(dg.decl.?);
|
||||
const src_loc = src.toSrcLoc(dg.decl.?, mod);
|
||||
dg.error_msg = try Module.ErrorMsg.create(dg.gpa, src_loc, format, args);
|
||||
return error.AnalysisFail;
|
||||
}
|
||||
@ -6484,6 +6485,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 un_op = f.air.instructions.items(.data)[inst].un_op;
|
||||
|
||||
const inst_ty = f.typeOfIndex(inst);
|
||||
@ -6495,7 +6497,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() }, .{ .tag_name = enum_ty }),
|
||||
try f.getLazyFnName(.{ .tag_name = enum_ty.getOwnerDecl(mod) }, .{ .tag_name = enum_ty }),
|
||||
});
|
||||
try f.writeCValue(writer, operand, .Other);
|
||||
try writer.writeAll(");\n");
|
||||
|
||||
@ -1538,7 +1538,7 @@ pub const CType = extern union {
|
||||
.forward, .forward_parameter => {
|
||||
self.storage = .{ .fwd = .{
|
||||
.base = .{ .tag = if (is_struct) .fwd_struct else .fwd_union },
|
||||
.data = ty.getOwnerDecl(),
|
||||
.data = ty.getOwnerDecl(mod),
|
||||
} };
|
||||
self.value = .{ .cty = initPayload(&self.storage.fwd) };
|
||||
},
|
||||
@ -1985,7 +1985,7 @@ 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(),
|
||||
.owner_decl = ty.getOwnerDecl(mod),
|
||||
.id = if (ty.unionTagTypeSafety()) |_| 0 else unreachable,
|
||||
} };
|
||||
return initPayload(unnamed_pl);
|
||||
@ -2124,7 +2124,7 @@ pub const CType = extern union {
|
||||
.forward, .forward_parameter, .complete, .parameter, .global => unreachable,
|
||||
.payload => if (ty.unionTagTypeSafety()) |_| {
|
||||
const data = cty.cast(Payload.Unnamed).?.data;
|
||||
return ty.getOwnerDecl() == data.owner_decl and data.id == 0;
|
||||
return ty.getOwnerDecl(mod) == data.owner_decl and data.id == 0;
|
||||
} else unreachable,
|
||||
},
|
||||
|
||||
@ -2242,7 +2242,7 @@ pub const CType = extern union {
|
||||
=> switch (self.kind) {
|
||||
.forward, .forward_parameter, .complete, .parameter, .global => unreachable,
|
||||
.payload => if (ty.unionTagTypeSafety()) |_| {
|
||||
autoHash(hasher, ty.getOwnerDecl());
|
||||
autoHash(hasher, ty.getOwnerDecl(mod));
|
||||
autoHash(hasher, @as(u32, 0));
|
||||
} else unreachable,
|
||||
},
|
||||
|
||||
@ -1177,7 +1177,7 @@ pub const Object = struct {
|
||||
var di_scope: ?*llvm.DIScope = null;
|
||||
|
||||
if (dg.object.di_builder) |dib| {
|
||||
di_file = try dg.object.getDIFile(gpa, decl.src_namespace.file_scope);
|
||||
di_file = try dg.object.getDIFile(gpa, mod.namespacePtr(decl.src_namespace).file_scope);
|
||||
|
||||
const line_number = decl.src_line + 1;
|
||||
const is_internal_linkage = decl.val.tag() != .extern_fn and
|
||||
@ -1505,7 +1505,7 @@ pub const Object = struct {
|
||||
return di_type;
|
||||
},
|
||||
.Enum => {
|
||||
const owner_decl_index = ty.getOwnerDecl();
|
||||
const owner_decl_index = ty.getOwnerDecl(mod);
|
||||
const owner_decl = o.module.declPtr(owner_decl_index);
|
||||
|
||||
if (!ty.hasRuntimeBitsIgnoreComptime(mod)) {
|
||||
@ -1558,7 +1558,7 @@ pub const Object = struct {
|
||||
@panic("TODO implement bigint debug enumerators to llvm int for 32-bit compiler builds");
|
||||
}
|
||||
|
||||
const di_file = try o.getDIFile(gpa, owner_decl.src_namespace.file_scope);
|
||||
const di_file = try o.getDIFile(gpa, mod.namespacePtr(owner_decl.src_namespace).file_scope);
|
||||
const di_scope = try o.namespaceToDebugScope(owner_decl.src_namespace);
|
||||
|
||||
const name = try ty.nameAlloc(gpa, o.module);
|
||||
@ -1737,13 +1737,13 @@ pub const Object = struct {
|
||||
}
|
||||
const name = try ty.nameAlloc(gpa, o.module);
|
||||
defer gpa.free(name);
|
||||
const owner_decl_index = ty.getOwnerDecl();
|
||||
const owner_decl_index = ty.getOwnerDecl(mod);
|
||||
const owner_decl = o.module.declPtr(owner_decl_index);
|
||||
const opaque_di_ty = dib.createForwardDeclType(
|
||||
DW.TAG.structure_type,
|
||||
name,
|
||||
try o.namespaceToDebugScope(owner_decl.src_namespace),
|
||||
try o.getDIFile(gpa, owner_decl.src_namespace.file_scope),
|
||||
try o.getDIFile(gpa, mod.namespacePtr(owner_decl.src_namespace).file_scope),
|
||||
owner_decl.src_node + 1,
|
||||
);
|
||||
// The recursive call to `lowerDebugType` va `namespaceToDebugScope`
|
||||
@ -2085,7 +2085,7 @@ pub const Object = struct {
|
||||
// into. Therefore we can satisfy this by making an empty namespace,
|
||||
// rather than changing the frontend to unnecessarily resolve the
|
||||
// struct field types.
|
||||
const owner_decl_index = ty.getOwnerDecl();
|
||||
const owner_decl_index = ty.getOwnerDecl(mod);
|
||||
const struct_di_ty = try o.makeEmptyNamespaceDIType(owner_decl_index);
|
||||
dib.replaceTemporary(fwd_decl, struct_di_ty);
|
||||
// The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType`
|
||||
@ -2096,7 +2096,7 @@ pub const Object = struct {
|
||||
}
|
||||
|
||||
if (!ty.hasRuntimeBitsIgnoreComptime(mod)) {
|
||||
const owner_decl_index = ty.getOwnerDecl();
|
||||
const owner_decl_index = ty.getOwnerDecl(mod);
|
||||
const struct_di_ty = try o.makeEmptyNamespaceDIType(owner_decl_index);
|
||||
dib.replaceTemporary(fwd_decl, struct_di_ty);
|
||||
// The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType`
|
||||
@ -2162,7 +2162,7 @@ pub const Object = struct {
|
||||
},
|
||||
.Union => {
|
||||
const compile_unit_scope = o.di_compile_unit.?.toScope();
|
||||
const owner_decl_index = ty.getOwnerDecl();
|
||||
const owner_decl_index = ty.getOwnerDecl(mod);
|
||||
|
||||
const name = try ty.nameAlloc(gpa, o.module);
|
||||
defer gpa.free(name);
|
||||
@ -2395,8 +2395,10 @@ pub const Object = struct {
|
||||
}
|
||||
}
|
||||
|
||||
fn namespaceToDebugScope(o: *Object, namespace: *const Module.Namespace) !*llvm.DIScope {
|
||||
if (namespace.parent == null) {
|
||||
fn namespaceToDebugScope(o: *Object, namespace_index: Module.Namespace.Index) !*llvm.DIScope {
|
||||
const mod = o.module;
|
||||
const namespace = mod.namespacePtr(namespace_index);
|
||||
if (namespace.parent == .none) {
|
||||
const di_file = try o.getDIFile(o.gpa, namespace.file_scope);
|
||||
return di_file.toScope();
|
||||
}
|
||||
@ -2408,12 +2410,13 @@ pub const Object = struct {
|
||||
/// Assertion `!isa<DIType>(Scope) && "shouldn't make a namespace scope for a type"'
|
||||
/// when targeting CodeView (Windows).
|
||||
fn makeEmptyNamespaceDIType(o: *Object, decl_index: Module.Decl.Index) !*llvm.DIType {
|
||||
const decl = o.module.declPtr(decl_index);
|
||||
const mod = o.module;
|
||||
const decl = mod.declPtr(decl_index);
|
||||
const fields: [0]*llvm.DIType = .{};
|
||||
return o.di_builder.?.createStructType(
|
||||
try o.namespaceToDebugScope(decl.src_namespace),
|
||||
decl.name, // TODO use fully qualified name
|
||||
try o.getDIFile(o.gpa, decl.src_namespace.file_scope),
|
||||
try o.getDIFile(o.gpa, mod.namespacePtr(decl.src_namespace).file_scope),
|
||||
decl.src_line + 1,
|
||||
0, // size in bits
|
||||
0, // align in bits
|
||||
@ -2434,14 +2437,14 @@ pub const Object = struct {
|
||||
const std_file = (mod.importPkg(std_pkg) catch unreachable).file;
|
||||
|
||||
const builtin_str: []const u8 = "builtin";
|
||||
const std_namespace = mod.declPtr(std_file.root_decl.unwrap().?).src_namespace;
|
||||
const std_namespace = mod.namespacePtr(mod.declPtr(std_file.root_decl.unwrap().?).src_namespace);
|
||||
const builtin_decl = std_namespace.decls
|
||||
.getKeyAdapted(builtin_str, Module.DeclAdapter{ .mod = mod }).?;
|
||||
|
||||
const stack_trace_str: []const u8 = "StackTrace";
|
||||
// buffer is only used for int_type, `builtin` is a struct.
|
||||
const builtin_ty = mod.declPtr(builtin_decl).val.toType();
|
||||
const builtin_namespace = builtin_ty.getNamespace().?;
|
||||
const builtin_namespace = builtin_ty.getNamespace(mod).?;
|
||||
const stack_trace_decl_index = builtin_namespace.decls
|
||||
.getKeyAdapted(stack_trace_str, Module.DeclAdapter{ .mod = mod }).?;
|
||||
const stack_trace_decl = mod.declPtr(stack_trace_decl_index);
|
||||
@ -2464,7 +2467,8 @@ pub const DeclGen = struct {
|
||||
fn todo(self: *DeclGen, comptime format: []const u8, args: anytype) Error {
|
||||
@setCold(true);
|
||||
assert(self.err_msg == null);
|
||||
const src_loc = LazySrcLoc.nodeOffset(0).toSrcLoc(self.decl);
|
||||
const mod = self.module;
|
||||
const src_loc = LazySrcLoc.nodeOffset(0).toSrcLoc(self.decl, mod);
|
||||
self.err_msg = try Module.ErrorMsg.create(self.gpa, src_loc, "TODO (LLVM): " ++ format, args);
|
||||
return error.CodegenFail;
|
||||
}
|
||||
@ -2536,7 +2540,7 @@ pub const DeclGen = struct {
|
||||
}
|
||||
|
||||
if (dg.object.di_builder) |dib| {
|
||||
const di_file = try dg.object.getDIFile(dg.gpa, decl.src_namespace.file_scope);
|
||||
const di_file = try dg.object.getDIFile(dg.gpa, mod.namespacePtr(decl.src_namespace).file_scope);
|
||||
|
||||
const line_number = decl.src_line + 1;
|
||||
const is_internal_linkage = !dg.module.decl_exports.contains(decl_index);
|
||||
@ -2837,15 +2841,11 @@ pub const DeclGen = struct {
|
||||
.Opaque => {
|
||||
if (t.ip_index == .anyopaque_type) return dg.context.intType(8);
|
||||
|
||||
const gop = try dg.object.type_map.getOrPutContext(gpa, t, .{ .mod = dg.module });
|
||||
const gop = try dg.object.type_map.getOrPutContext(gpa, t, .{ .mod = mod });
|
||||
if (gop.found_existing) return gop.value_ptr.*;
|
||||
|
||||
// The Type memory is ephemeral; since we want to store a longer-lived
|
||||
// reference, we need to copy it here.
|
||||
gop.key_ptr.* = try t.copy(dg.object.type_map_arena.allocator());
|
||||
|
||||
const opaque_obj = t.castTag(.@"opaque").?.data;
|
||||
const name = try opaque_obj.getFullyQualifiedName(dg.module);
|
||||
const opaque_type = mod.intern_pool.indexToKey(t.ip_index).opaque_type;
|
||||
const name = try mod.opaqueFullyQualifiedName(opaque_type);
|
||||
defer gpa.free(name);
|
||||
|
||||
const llvm_struct_ty = dg.context.structCreateNamed(name);
|
||||
@ -2931,7 +2931,7 @@ pub const DeclGen = struct {
|
||||
},
|
||||
.ErrorSet => return dg.context.intType(16),
|
||||
.Struct => {
|
||||
const gop = try dg.object.type_map.getOrPutContext(gpa, t, .{ .mod = dg.module });
|
||||
const gop = try dg.object.type_map.getOrPutContext(gpa, t, .{ .mod = mod });
|
||||
if (gop.found_existing) return gop.value_ptr.*;
|
||||
|
||||
// The Type memory is ephemeral; since we want to store a longer-lived
|
||||
@ -2999,7 +2999,7 @@ pub const DeclGen = struct {
|
||||
return int_llvm_ty;
|
||||
}
|
||||
|
||||
const name = try struct_obj.getFullyQualifiedName(dg.module);
|
||||
const name = try struct_obj.getFullyQualifiedName(mod);
|
||||
defer gpa.free(name);
|
||||
|
||||
const llvm_struct_ty = dg.context.structCreateNamed(name);
|
||||
@ -3057,7 +3057,7 @@ pub const DeclGen = struct {
|
||||
return llvm_struct_ty;
|
||||
},
|
||||
.Union => {
|
||||
const gop = try dg.object.type_map.getOrPutContext(gpa, t, .{ .mod = dg.module });
|
||||
const gop = try dg.object.type_map.getOrPutContext(gpa, t, .{ .mod = mod });
|
||||
if (gop.found_existing) return gop.value_ptr.*;
|
||||
|
||||
// The Type memory is ephemeral; since we want to store a longer-lived
|
||||
@ -3080,7 +3080,7 @@ pub const DeclGen = struct {
|
||||
return enum_tag_llvm_ty;
|
||||
}
|
||||
|
||||
const name = try union_obj.getFullyQualifiedName(dg.module);
|
||||
const name = try union_obj.getFullyQualifiedName(mod);
|
||||
defer gpa.free(name);
|
||||
|
||||
const llvm_union_ty = dg.context.structCreateNamed(name);
|
||||
@ -6131,7 +6131,7 @@ pub const FuncGen = struct {
|
||||
const func = self.air.values[ty_pl.payload].castTag(.function).?.data;
|
||||
const decl_index = func.owner_decl;
|
||||
const decl = mod.declPtr(decl_index);
|
||||
const di_file = try self.dg.object.getDIFile(self.gpa, decl.src_namespace.file_scope);
|
||||
const di_file = try self.dg.object.getDIFile(self.gpa, mod.namespacePtr(decl.src_namespace).file_scope);
|
||||
self.di_file = di_file;
|
||||
const line_number = decl.src_line + 1;
|
||||
const cur_debug_location = self.builder.getCurrentDebugLocation2();
|
||||
@ -6193,7 +6193,7 @@ pub const FuncGen = struct {
|
||||
const func = self.air.values[ty_pl.payload].castTag(.function).?.data;
|
||||
const mod = self.dg.module;
|
||||
const decl = mod.declPtr(func.owner_decl);
|
||||
const di_file = try self.dg.object.getDIFile(self.gpa, decl.src_namespace.file_scope);
|
||||
const di_file = try self.dg.object.getDIFile(self.gpa, mod.namespacePtr(decl.src_namespace).file_scope);
|
||||
self.di_file = di_file;
|
||||
const old = self.dbg_inlined.pop();
|
||||
self.di_scope = old.scope;
|
||||
@ -8853,7 +8853,8 @@ pub const FuncGen = struct {
|
||||
}
|
||||
|
||||
fn getIsNamedEnumValueFunction(self: *FuncGen, enum_ty: Type) !*llvm.Value {
|
||||
const enum_decl = enum_ty.getOwnerDecl();
|
||||
const mod = self.dg.module;
|
||||
const enum_decl = enum_ty.getOwnerDecl(mod);
|
||||
|
||||
// TODO: detect when the type changes and re-emit this function.
|
||||
const gop = try self.dg.object.named_enum_map.getOrPut(self.dg.gpa, enum_decl);
|
||||
@ -8864,7 +8865,6 @@ pub const FuncGen = struct {
|
||||
defer arena_allocator.deinit();
|
||||
const arena = arena_allocator.allocator();
|
||||
|
||||
const mod = self.dg.module;
|
||||
const fqn = try mod.declPtr(enum_decl).getFullyQualifiedName(mod);
|
||||
defer self.gpa.free(fqn);
|
||||
const llvm_fn_name = try std.fmt.allocPrintZ(arena, "__zig_is_named_enum_value_{s}", .{fqn});
|
||||
@ -8931,7 +8931,8 @@ pub const FuncGen = struct {
|
||||
}
|
||||
|
||||
fn getEnumTagNameFunction(self: *FuncGen, enum_ty: Type) !*llvm.Value {
|
||||
const enum_decl = enum_ty.getOwnerDecl();
|
||||
const mod = self.dg.module;
|
||||
const enum_decl = enum_ty.getOwnerDecl(mod);
|
||||
|
||||
// TODO: detect when the type changes and re-emit this function.
|
||||
const gop = try self.dg.object.decl_map.getOrPut(self.dg.gpa, enum_decl);
|
||||
@ -8942,7 +8943,6 @@ pub const FuncGen = struct {
|
||||
defer arena_allocator.deinit();
|
||||
const arena = arena_allocator.allocator();
|
||||
|
||||
const mod = self.dg.module;
|
||||
const fqn = try mod.declPtr(enum_decl).getFullyQualifiedName(mod);
|
||||
defer self.gpa.free(fqn);
|
||||
const llvm_fn_name = try std.fmt.allocPrintZ(arena, "__zig_tag_name_{s}", .{fqn});
|
||||
|
||||
@ -218,8 +218,9 @@ pub const DeclGen = struct {
|
||||
|
||||
pub fn fail(self: *DeclGen, comptime format: []const u8, args: anytype) Error {
|
||||
@setCold(true);
|
||||
const mod = self.module;
|
||||
const src = LazySrcLoc.nodeOffset(0);
|
||||
const src_loc = src.toSrcLoc(self.module.declPtr(self.decl_index));
|
||||
const src_loc = src.toSrcLoc(self.module.declPtr(self.decl_index), mod);
|
||||
assert(self.error_msg == null);
|
||||
self.error_msg = try Module.ErrorMsg.create(self.module.gpa, src_loc, format, args);
|
||||
return error.CodegenFail;
|
||||
@ -2775,7 +2776,10 @@ pub const DeclGen = struct {
|
||||
|
||||
fn airDbgStmt(self: *DeclGen, inst: Air.Inst.Index) !void {
|
||||
const dbg_stmt = self.air.instructions.items(.data)[inst].dbg_stmt;
|
||||
const src_fname_id = try self.spv.resolveSourceFileName(self.module.declPtr(self.decl_index));
|
||||
const src_fname_id = try self.spv.resolveSourceFileName(
|
||||
self.module,
|
||||
self.module.declPtr(self.decl_index),
|
||||
);
|
||||
try self.func.body.emit(self.spv.gpa, .OpLine, .{
|
||||
.file = src_fname_id,
|
||||
.line = dbg_stmt.line,
|
||||
@ -3192,6 +3196,7 @@ pub const DeclGen = struct {
|
||||
}
|
||||
|
||||
fn airAssembly(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
|
||||
const mod = self.module;
|
||||
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
|
||||
const extra = self.air.extraData(Air.Asm, ty_pl.payload);
|
||||
|
||||
@ -3274,7 +3279,7 @@ pub const DeclGen = struct {
|
||||
assert(as.errors.items.len != 0);
|
||||
assert(self.error_msg == null);
|
||||
const loc = LazySrcLoc.nodeOffset(0);
|
||||
const src_loc = loc.toSrcLoc(self.module.declPtr(self.decl_index));
|
||||
const src_loc = loc.toSrcLoc(self.module.declPtr(self.decl_index), mod);
|
||||
self.error_msg = try Module.ErrorMsg.create(self.module.gpa, src_loc, "failed to assemble SPIR-V inline assembly", .{});
|
||||
const notes = try self.module.gpa.alloc(Module.ErrorMsg, as.errors.items.len);
|
||||
|
||||
|
||||
@ -390,8 +390,8 @@ pub fn addFunction(self: *Module, decl_index: Decl.Index, func: Fn) !void {
|
||||
/// Fetch the result-id of an OpString instruction that encodes the path of the source
|
||||
/// file of the decl. This function may also emit an OpSource with source-level information regarding
|
||||
/// the decl.
|
||||
pub fn resolveSourceFileName(self: *Module, decl: *ZigDecl) !IdRef {
|
||||
const path = decl.getFileScope().sub_file_path;
|
||||
pub fn resolveSourceFileName(self: *Module, zig_module: *ZigModule, zig_decl: *ZigDecl) !IdRef {
|
||||
const path = zig_decl.getFileScope(zig_module).sub_file_path;
|
||||
const result = try self.source_file_names.getOrPut(self.gpa, path);
|
||||
if (!result.found_existing) {
|
||||
const file_result_id = self.allocId();
|
||||
|
||||
@ -99,7 +99,7 @@ fn dumpStatusReport() !void {
|
||||
allocator,
|
||||
anal.body,
|
||||
anal.body_index,
|
||||
block.namespace.file_scope,
|
||||
mod.namespacePtr(block.namespace).file_scope,
|
||||
block_src_decl.src_node,
|
||||
6, // indent
|
||||
stderr,
|
||||
@ -108,7 +108,7 @@ fn dumpStatusReport() !void {
|
||||
else => |e| return e,
|
||||
};
|
||||
try stderr.writeAll(" For full context, use the command\n zig ast-check -t ");
|
||||
try writeFilePath(block.namespace.file_scope, stderr);
|
||||
try writeFilePath(mod.namespacePtr(block.namespace).file_scope, stderr);
|
||||
try stderr.writeAll("\n\n");
|
||||
|
||||
var parent = anal.parent;
|
||||
@ -121,7 +121,7 @@ fn dumpStatusReport() !void {
|
||||
print_zir.renderSingleInstruction(
|
||||
allocator,
|
||||
curr.body[curr.body_index],
|
||||
curr.block.namespace.file_scope,
|
||||
mod.namespacePtr(curr.block.namespace).file_scope,
|
||||
curr_block_src_decl.src_node,
|
||||
6, // indent
|
||||
stderr,
|
||||
@ -148,7 +148,7 @@ fn writeFilePath(file: *Module.File, stream: anytype) !void {
|
||||
}
|
||||
|
||||
fn writeFullyQualifiedDeclWithFile(mod: *Module, decl: *Decl, stream: anytype) !void {
|
||||
try writeFilePath(decl.getFileScope(), stream);
|
||||
try writeFilePath(decl.getFileScope(mod), stream);
|
||||
try stream.writeAll(": ");
|
||||
try decl.renderFullyQualifiedDebugName(mod, stream);
|
||||
}
|
||||
|
||||
@ -1129,8 +1129,8 @@ pub const File = struct {
|
||||
Type.anyerror };
|
||||
}
|
||||
|
||||
pub fn getDecl(self: LazySymbol) Module.Decl.OptionalIndex {
|
||||
return Module.Decl.OptionalIndex.init(self.ty.getOwnerDeclOrNull());
|
||||
pub fn getDecl(self: LazySymbol, mod: *Module) Module.Decl.OptionalIndex {
|
||||
return Module.Decl.OptionalIndex.init(self.ty.getOwnerDeclOrNull(mod));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -1032,20 +1032,20 @@ fn freeAtom(self: *Coff, atom_index: Atom.Index) void {
|
||||
self.getAtomPtr(atom_index).sym_index = 0;
|
||||
}
|
||||
|
||||
pub fn updateFunc(self: *Coff, module: *Module, func: *Module.Fn, air: Air, liveness: Liveness) !void {
|
||||
pub fn updateFunc(self: *Coff, mod: *Module, func: *Module.Fn, air: Air, liveness: Liveness) !void {
|
||||
if (build_options.skip_non_native and builtin.object_format != .coff) {
|
||||
@panic("Attempted to compile for object format that was disabled by build configuration");
|
||||
}
|
||||
if (build_options.have_llvm) {
|
||||
if (self.llvm_object) |llvm_object| {
|
||||
return llvm_object.updateFunc(module, func, air, liveness);
|
||||
return llvm_object.updateFunc(mod, func, air, liveness);
|
||||
}
|
||||
}
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
const decl_index = func.owner_decl;
|
||||
const decl = module.declPtr(decl_index);
|
||||
const decl = mod.declPtr(decl_index);
|
||||
|
||||
const atom_index = try self.getOrCreateAtomForDecl(decl_index);
|
||||
self.freeUnnamedConsts(decl_index);
|
||||
@ -1056,7 +1056,7 @@ pub fn updateFunc(self: *Coff, module: *Module, func: *Module.Fn, air: Air, live
|
||||
|
||||
const res = try codegen.generateFunction(
|
||||
&self.base,
|
||||
decl.srcLoc(),
|
||||
decl.srcLoc(mod),
|
||||
func,
|
||||
air,
|
||||
liveness,
|
||||
@ -1067,7 +1067,7 @@ pub fn updateFunc(self: *Coff, module: *Module, func: *Module.Fn, air: Air, live
|
||||
.ok => code_buffer.items,
|
||||
.fail => |em| {
|
||||
decl.analysis = .codegen_failure;
|
||||
try module.failed_decls.put(module.gpa, decl_index, em);
|
||||
try mod.failed_decls.put(mod.gpa, decl_index, em);
|
||||
return;
|
||||
},
|
||||
};
|
||||
@ -1076,7 +1076,7 @@ pub fn updateFunc(self: *Coff, module: *Module, func: *Module.Fn, air: Air, live
|
||||
|
||||
// Since we updated the vaddr and the size, each corresponding export
|
||||
// symbol also needs to be updated.
|
||||
return self.updateDeclExports(module, decl_index, module.getDeclExports(decl_index));
|
||||
return self.updateDeclExports(mod, decl_index, mod.getDeclExports(decl_index));
|
||||
}
|
||||
|
||||
pub fn lowerUnnamedConst(self: *Coff, tv: TypedValue, decl_index: Module.Decl.Index) !u32 {
|
||||
@ -1110,7 +1110,7 @@ pub fn lowerUnnamedConst(self: *Coff, tv: TypedValue, decl_index: Module.Decl.In
|
||||
sym.section_number = @intToEnum(coff.SectionNumber, self.rdata_section_index.? + 1);
|
||||
}
|
||||
|
||||
const res = try codegen.generateSymbol(&self.base, decl.srcLoc(), tv, &code_buffer, .none, .{
|
||||
const res = try codegen.generateSymbol(&self.base, decl.srcLoc(mod), tv, &code_buffer, .none, .{
|
||||
.parent_atom_index = self.getAtom(atom_index).getSymbolIndex().?,
|
||||
});
|
||||
var code = switch (res) {
|
||||
@ -1141,19 +1141,19 @@ pub fn lowerUnnamedConst(self: *Coff, tv: TypedValue, decl_index: Module.Decl.In
|
||||
|
||||
pub fn updateDecl(
|
||||
self: *Coff,
|
||||
module: *Module,
|
||||
mod: *Module,
|
||||
decl_index: Module.Decl.Index,
|
||||
) link.File.UpdateDeclError!void {
|
||||
if (build_options.skip_non_native and builtin.object_format != .coff) {
|
||||
@panic("Attempted to compile for object format that was disabled by build configuration");
|
||||
}
|
||||
if (build_options.have_llvm) {
|
||||
if (self.llvm_object) |llvm_object| return llvm_object.updateDecl(module, decl_index);
|
||||
if (self.llvm_object) |llvm_object| return llvm_object.updateDecl(mod, decl_index);
|
||||
}
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
const decl = module.declPtr(decl_index);
|
||||
const decl = mod.declPtr(decl_index);
|
||||
|
||||
if (decl.val.tag() == .extern_fn) {
|
||||
return; // TODO Should we do more when front-end analyzed extern decl?
|
||||
@ -1173,7 +1173,7 @@ pub fn updateDecl(
|
||||
defer code_buffer.deinit();
|
||||
|
||||
const decl_val = if (decl.val.castTag(.variable)) |payload| payload.data.init else decl.val;
|
||||
const res = try codegen.generateSymbol(&self.base, decl.srcLoc(), .{
|
||||
const res = try codegen.generateSymbol(&self.base, decl.srcLoc(mod), .{
|
||||
.ty = decl.ty,
|
||||
.val = decl_val,
|
||||
}, &code_buffer, .none, .{
|
||||
@ -1183,7 +1183,7 @@ pub fn updateDecl(
|
||||
.ok => code_buffer.items,
|
||||
.fail => |em| {
|
||||
decl.analysis = .codegen_failure;
|
||||
try module.failed_decls.put(module.gpa, decl_index, em);
|
||||
try mod.failed_decls.put(mod.gpa, decl_index, em);
|
||||
return;
|
||||
},
|
||||
};
|
||||
@ -1192,7 +1192,7 @@ pub fn updateDecl(
|
||||
|
||||
// Since we updated the vaddr and the size, each corresponding export
|
||||
// symbol also needs to be updated.
|
||||
return self.updateDeclExports(module, decl_index, module.getDeclExports(decl_index));
|
||||
return self.updateDeclExports(mod, decl_index, mod.getDeclExports(decl_index));
|
||||
}
|
||||
|
||||
fn updateLazySymbolAtom(
|
||||
@ -1217,8 +1217,8 @@ fn updateLazySymbolAtom(
|
||||
const atom = self.getAtomPtr(atom_index);
|
||||
const local_sym_index = atom.getSymbolIndex().?;
|
||||
|
||||
const src = if (sym.ty.getOwnerDeclOrNull()) |owner_decl|
|
||||
mod.declPtr(owner_decl).srcLoc()
|
||||
const src = if (sym.ty.getOwnerDeclOrNull(mod)) |owner_decl|
|
||||
mod.declPtr(owner_decl).srcLoc(mod)
|
||||
else
|
||||
Module.SrcLoc{
|
||||
.file_scope = undefined,
|
||||
@ -1262,7 +1262,8 @@ fn updateLazySymbolAtom(
|
||||
}
|
||||
|
||||
pub fn getOrCreateAtomForLazySymbol(self: *Coff, sym: link.File.LazySymbol) !Atom.Index {
|
||||
const gop = try self.lazy_syms.getOrPut(self.base.allocator, sym.getDecl());
|
||||
const mod = self.base.options.module.?;
|
||||
const gop = try self.lazy_syms.getOrPut(self.base.allocator, sym.getDecl(mod));
|
||||
errdefer _ = if (!gop.found_existing) self.lazy_syms.pop();
|
||||
if (!gop.found_existing) gop.value_ptr.* = .{};
|
||||
const metadata: struct { atom: *Atom.Index, state: *LazySymbolMetadata.State } = switch (sym.kind) {
|
||||
@ -1277,7 +1278,7 @@ pub fn getOrCreateAtomForLazySymbol(self: *Coff, sym: link.File.LazySymbol) !Ato
|
||||
metadata.state.* = .pending_flush;
|
||||
const atom = metadata.atom.*;
|
||||
// anyerror needs to be deferred until flushModule
|
||||
if (sym.getDecl() != .none) try self.updateLazySymbolAtom(sym, atom, switch (sym.kind) {
|
||||
if (sym.getDecl(mod) != .none) try self.updateLazySymbolAtom(sym, atom, switch (sym.kind) {
|
||||
.code => self.text_section_index.?,
|
||||
.const_data => self.rdata_section_index.?,
|
||||
});
|
||||
@ -1411,7 +1412,7 @@ pub fn freeDecl(self: *Coff, decl_index: Module.Decl.Index) void {
|
||||
|
||||
pub fn updateDeclExports(
|
||||
self: *Coff,
|
||||
module: *Module,
|
||||
mod: *Module,
|
||||
decl_index: Module.Decl.Index,
|
||||
exports: []const *Module.Export,
|
||||
) link.File.UpdateDeclExportsError!void {
|
||||
@ -1423,7 +1424,7 @@ pub fn updateDeclExports(
|
||||
// Even in the case of LLVM, we need to notice certain exported symbols in order to
|
||||
// detect the default subsystem.
|
||||
for (exports) |exp| {
|
||||
const exported_decl = module.declPtr(exp.exported_decl);
|
||||
const exported_decl = mod.declPtr(exp.exported_decl);
|
||||
if (exported_decl.getFunction() == null) continue;
|
||||
const winapi_cc = switch (self.base.options.target.cpu.arch) {
|
||||
.x86 => std.builtin.CallingConvention.Stdcall,
|
||||
@ -1433,23 +1434,23 @@ pub fn updateDeclExports(
|
||||
if (decl_cc == .C and mem.eql(u8, exp.options.name, "main") and
|
||||
self.base.options.link_libc)
|
||||
{
|
||||
module.stage1_flags.have_c_main = true;
|
||||
mod.stage1_flags.have_c_main = true;
|
||||
} else if (decl_cc == winapi_cc and self.base.options.target.os.tag == .windows) {
|
||||
if (mem.eql(u8, exp.options.name, "WinMain")) {
|
||||
module.stage1_flags.have_winmain = true;
|
||||
mod.stage1_flags.have_winmain = true;
|
||||
} else if (mem.eql(u8, exp.options.name, "wWinMain")) {
|
||||
module.stage1_flags.have_wwinmain = true;
|
||||
mod.stage1_flags.have_wwinmain = true;
|
||||
} else if (mem.eql(u8, exp.options.name, "WinMainCRTStartup")) {
|
||||
module.stage1_flags.have_winmain_crt_startup = true;
|
||||
mod.stage1_flags.have_winmain_crt_startup = true;
|
||||
} else if (mem.eql(u8, exp.options.name, "wWinMainCRTStartup")) {
|
||||
module.stage1_flags.have_wwinmain_crt_startup = true;
|
||||
mod.stage1_flags.have_wwinmain_crt_startup = true;
|
||||
} else if (mem.eql(u8, exp.options.name, "DllMainCRTStartup")) {
|
||||
module.stage1_flags.have_dllmain_crt_startup = true;
|
||||
mod.stage1_flags.have_dllmain_crt_startup = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (self.llvm_object) |llvm_object| return llvm_object.updateDeclExports(module, decl_index, exports);
|
||||
if (self.llvm_object) |llvm_object| return llvm_object.updateDeclExports(mod, decl_index, exports);
|
||||
}
|
||||
|
||||
const tracy = trace(@src());
|
||||
@ -1457,7 +1458,7 @@ pub fn updateDeclExports(
|
||||
|
||||
const gpa = self.base.allocator;
|
||||
|
||||
const decl = module.declPtr(decl_index);
|
||||
const decl = mod.declPtr(decl_index);
|
||||
const atom_index = try self.getOrCreateAtomForDecl(decl_index);
|
||||
const atom = self.getAtom(atom_index);
|
||||
const decl_sym = atom.getSymbol(self);
|
||||
@ -1468,12 +1469,12 @@ pub fn updateDeclExports(
|
||||
|
||||
if (exp.options.section) |section_name| {
|
||||
if (!mem.eql(u8, section_name, ".text")) {
|
||||
try module.failed_exports.putNoClobber(
|
||||
module.gpa,
|
||||
try mod.failed_exports.putNoClobber(
|
||||
mod.gpa,
|
||||
exp,
|
||||
try Module.ErrorMsg.create(
|
||||
gpa,
|
||||
decl.srcLoc(),
|
||||
decl.srcLoc(mod),
|
||||
"Unimplemented: ExportOptions.section",
|
||||
.{},
|
||||
),
|
||||
@ -1483,12 +1484,12 @@ pub fn updateDeclExports(
|
||||
}
|
||||
|
||||
if (exp.options.linkage == .LinkOnce) {
|
||||
try module.failed_exports.putNoClobber(
|
||||
module.gpa,
|
||||
try mod.failed_exports.putNoClobber(
|
||||
mod.gpa,
|
||||
exp,
|
||||
try Module.ErrorMsg.create(
|
||||
gpa,
|
||||
decl.srcLoc(),
|
||||
decl.srcLoc(mod),
|
||||
"Unimplemented: GlobalLinkage.LinkOnce",
|
||||
.{},
|
||||
),
|
||||
|
||||
@ -2597,7 +2597,7 @@ pub fn flushModule(self: *Dwarf, module: *Module) !void {
|
||||
|
||||
fn addDIFile(self: *Dwarf, mod: *Module, decl_index: Module.Decl.Index) !u28 {
|
||||
const decl = mod.declPtr(decl_index);
|
||||
const file_scope = decl.getFileScope();
|
||||
const file_scope = decl.getFileScope(mod);
|
||||
const gop = try self.di_files.getOrPut(self.allocator, file_scope);
|
||||
if (!gop.found_existing) {
|
||||
switch (self.bin_file.tag) {
|
||||
|
||||
@ -2414,7 +2414,8 @@ pub fn freeDecl(self: *Elf, decl_index: Module.Decl.Index) void {
|
||||
}
|
||||
|
||||
pub fn getOrCreateAtomForLazySymbol(self: *Elf, sym: File.LazySymbol) !Atom.Index {
|
||||
const gop = try self.lazy_syms.getOrPut(self.base.allocator, sym.getDecl());
|
||||
const mod = self.base.options.module.?;
|
||||
const gop = try self.lazy_syms.getOrPut(self.base.allocator, sym.getDecl(mod));
|
||||
errdefer _ = if (!gop.found_existing) self.lazy_syms.pop();
|
||||
if (!gop.found_existing) gop.value_ptr.* = .{};
|
||||
const metadata: struct { atom: *Atom.Index, state: *LazySymbolMetadata.State } = switch (sym.kind) {
|
||||
@ -2429,7 +2430,7 @@ pub fn getOrCreateAtomForLazySymbol(self: *Elf, sym: File.LazySymbol) !Atom.Inde
|
||||
metadata.state.* = .pending_flush;
|
||||
const atom = metadata.atom.*;
|
||||
// anyerror needs to be deferred until flushModule
|
||||
if (sym.getDecl() != .none) try self.updateLazySymbolAtom(sym, atom, switch (sym.kind) {
|
||||
if (sym.getDecl(mod) != .none) try self.updateLazySymbolAtom(sym, atom, switch (sym.kind) {
|
||||
.code => self.text_section_index.?,
|
||||
.const_data => self.rodata_section_index.?,
|
||||
});
|
||||
@ -2573,19 +2574,19 @@ fn updateDeclCode(self: *Elf, decl_index: Module.Decl.Index, code: []const u8, s
|
||||
return local_sym;
|
||||
}
|
||||
|
||||
pub fn updateFunc(self: *Elf, module: *Module, func: *Module.Fn, air: Air, liveness: Liveness) !void {
|
||||
pub fn updateFunc(self: *Elf, mod: *Module, func: *Module.Fn, air: Air, liveness: Liveness) !void {
|
||||
if (build_options.skip_non_native and builtin.object_format != .elf) {
|
||||
@panic("Attempted to compile for object format that was disabled by build configuration");
|
||||
}
|
||||
if (build_options.have_llvm) {
|
||||
if (self.llvm_object) |llvm_object| return llvm_object.updateFunc(module, func, air, liveness);
|
||||
if (self.llvm_object) |llvm_object| return llvm_object.updateFunc(mod, func, air, liveness);
|
||||
}
|
||||
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
const decl_index = func.owner_decl;
|
||||
const decl = module.declPtr(decl_index);
|
||||
const decl = mod.declPtr(decl_index);
|
||||
|
||||
const atom_index = try self.getOrCreateAtomForDecl(decl_index);
|
||||
self.freeUnnamedConsts(decl_index);
|
||||
@ -2594,28 +2595,28 @@ pub fn updateFunc(self: *Elf, module: *Module, func: *Module.Fn, air: Air, liven
|
||||
var code_buffer = std.ArrayList(u8).init(self.base.allocator);
|
||||
defer code_buffer.deinit();
|
||||
|
||||
var decl_state: ?Dwarf.DeclState = if (self.dwarf) |*dw| try dw.initDeclState(module, decl_index) else null;
|
||||
var decl_state: ?Dwarf.DeclState = if (self.dwarf) |*dw| try dw.initDeclState(mod, decl_index) else null;
|
||||
defer if (decl_state) |*ds| ds.deinit();
|
||||
|
||||
const res = if (decl_state) |*ds|
|
||||
try codegen.generateFunction(&self.base, decl.srcLoc(), func, air, liveness, &code_buffer, .{
|
||||
try codegen.generateFunction(&self.base, decl.srcLoc(mod), func, air, liveness, &code_buffer, .{
|
||||
.dwarf = ds,
|
||||
})
|
||||
else
|
||||
try codegen.generateFunction(&self.base, decl.srcLoc(), func, air, liveness, &code_buffer, .none);
|
||||
try codegen.generateFunction(&self.base, decl.srcLoc(mod), func, air, liveness, &code_buffer, .none);
|
||||
|
||||
const code = switch (res) {
|
||||
.ok => code_buffer.items,
|
||||
.fail => |em| {
|
||||
decl.analysis = .codegen_failure;
|
||||
try module.failed_decls.put(module.gpa, decl_index, em);
|
||||
try mod.failed_decls.put(mod.gpa, decl_index, em);
|
||||
return;
|
||||
},
|
||||
};
|
||||
const local_sym = try self.updateDeclCode(decl_index, code, elf.STT_FUNC);
|
||||
if (decl_state) |*ds| {
|
||||
try self.dwarf.?.commitDeclState(
|
||||
module,
|
||||
mod,
|
||||
decl_index,
|
||||
local_sym.st_value,
|
||||
local_sym.st_size,
|
||||
@ -2625,25 +2626,25 @@ pub fn updateFunc(self: *Elf, module: *Module, func: *Module.Fn, air: Air, liven
|
||||
|
||||
// Since we updated the vaddr and the size, each corresponding export
|
||||
// symbol also needs to be updated.
|
||||
return self.updateDeclExports(module, decl_index, module.getDeclExports(decl_index));
|
||||
return self.updateDeclExports(mod, decl_index, mod.getDeclExports(decl_index));
|
||||
}
|
||||
|
||||
pub fn updateDecl(
|
||||
self: *Elf,
|
||||
module: *Module,
|
||||
mod: *Module,
|
||||
decl_index: Module.Decl.Index,
|
||||
) File.UpdateDeclError!void {
|
||||
if (build_options.skip_non_native and builtin.object_format != .elf) {
|
||||
@panic("Attempted to compile for object format that was disabled by build configuration");
|
||||
}
|
||||
if (build_options.have_llvm) {
|
||||
if (self.llvm_object) |llvm_object| return llvm_object.updateDecl(module, decl_index);
|
||||
if (self.llvm_object) |llvm_object| return llvm_object.updateDecl(mod, decl_index);
|
||||
}
|
||||
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
const decl = module.declPtr(decl_index);
|
||||
const decl = mod.declPtr(decl_index);
|
||||
|
||||
if (decl.val.tag() == .extern_fn) {
|
||||
return; // TODO Should we do more when front-end analyzed extern decl?
|
||||
@ -2662,13 +2663,13 @@ pub fn updateDecl(
|
||||
var code_buffer = std.ArrayList(u8).init(self.base.allocator);
|
||||
defer code_buffer.deinit();
|
||||
|
||||
var decl_state: ?Dwarf.DeclState = if (self.dwarf) |*dw| try dw.initDeclState(module, decl_index) else null;
|
||||
var decl_state: ?Dwarf.DeclState = if (self.dwarf) |*dw| try dw.initDeclState(mod, decl_index) else null;
|
||||
defer if (decl_state) |*ds| ds.deinit();
|
||||
|
||||
// TODO implement .debug_info for global variables
|
||||
const decl_val = if (decl.val.castTag(.variable)) |payload| payload.data.init else decl.val;
|
||||
const res = if (decl_state) |*ds|
|
||||
try codegen.generateSymbol(&self.base, decl.srcLoc(), .{
|
||||
try codegen.generateSymbol(&self.base, decl.srcLoc(mod), .{
|
||||
.ty = decl.ty,
|
||||
.val = decl_val,
|
||||
}, &code_buffer, .{
|
||||
@ -2677,7 +2678,7 @@ pub fn updateDecl(
|
||||
.parent_atom_index = atom.getSymbolIndex().?,
|
||||
})
|
||||
else
|
||||
try codegen.generateSymbol(&self.base, decl.srcLoc(), .{
|
||||
try codegen.generateSymbol(&self.base, decl.srcLoc(mod), .{
|
||||
.ty = decl.ty,
|
||||
.val = decl_val,
|
||||
}, &code_buffer, .none, .{
|
||||
@ -2688,7 +2689,7 @@ pub fn updateDecl(
|
||||
.ok => code_buffer.items,
|
||||
.fail => |em| {
|
||||
decl.analysis = .codegen_failure;
|
||||
try module.failed_decls.put(module.gpa, decl_index, em);
|
||||
try mod.failed_decls.put(mod.gpa, decl_index, em);
|
||||
return;
|
||||
},
|
||||
};
|
||||
@ -2696,7 +2697,7 @@ pub fn updateDecl(
|
||||
const local_sym = try self.updateDeclCode(decl_index, code, elf.STT_OBJECT);
|
||||
if (decl_state) |*ds| {
|
||||
try self.dwarf.?.commitDeclState(
|
||||
module,
|
||||
mod,
|
||||
decl_index,
|
||||
local_sym.st_value,
|
||||
local_sym.st_size,
|
||||
@ -2706,7 +2707,7 @@ pub fn updateDecl(
|
||||
|
||||
// Since we updated the vaddr and the size, each corresponding export
|
||||
// symbol also needs to be updated.
|
||||
return self.updateDeclExports(module, decl_index, module.getDeclExports(decl_index));
|
||||
return self.updateDeclExports(mod, decl_index, mod.getDeclExports(decl_index));
|
||||
}
|
||||
|
||||
fn updateLazySymbolAtom(
|
||||
@ -2735,8 +2736,8 @@ fn updateLazySymbolAtom(
|
||||
const atom = self.getAtom(atom_index);
|
||||
const local_sym_index = atom.getSymbolIndex().?;
|
||||
|
||||
const src = if (sym.ty.getOwnerDeclOrNull()) |owner_decl|
|
||||
mod.declPtr(owner_decl).srcLoc()
|
||||
const src = if (sym.ty.getOwnerDeclOrNull(mod)) |owner_decl|
|
||||
mod.declPtr(owner_decl).srcLoc(mod)
|
||||
else
|
||||
Module.SrcLoc{
|
||||
.file_scope = undefined,
|
||||
@ -2812,7 +2813,7 @@ pub fn lowerUnnamedConst(self: *Elf, typed_value: TypedValue, decl_index: Module
|
||||
|
||||
const atom_index = try self.createAtom();
|
||||
|
||||
const res = try codegen.generateSymbol(&self.base, decl.srcLoc(), typed_value, &code_buffer, .{
|
||||
const res = try codegen.generateSymbol(&self.base, decl.srcLoc(mod), typed_value, &code_buffer, .{
|
||||
.none = {},
|
||||
}, .{
|
||||
.parent_atom_index = self.getAtom(atom_index).getSymbolIndex().?,
|
||||
@ -2853,7 +2854,7 @@ pub fn lowerUnnamedConst(self: *Elf, typed_value: TypedValue, decl_index: Module
|
||||
|
||||
pub fn updateDeclExports(
|
||||
self: *Elf,
|
||||
module: *Module,
|
||||
mod: *Module,
|
||||
decl_index: Module.Decl.Index,
|
||||
exports: []const *Module.Export,
|
||||
) File.UpdateDeclExportsError!void {
|
||||
@ -2861,7 +2862,7 @@ pub fn updateDeclExports(
|
||||
@panic("Attempted to compile for object format that was disabled by build configuration");
|
||||
}
|
||||
if (build_options.have_llvm) {
|
||||
if (self.llvm_object) |llvm_object| return llvm_object.updateDeclExports(module, decl_index, exports);
|
||||
if (self.llvm_object) |llvm_object| return llvm_object.updateDeclExports(mod, decl_index, exports);
|
||||
}
|
||||
|
||||
const tracy = trace(@src());
|
||||
@ -2869,7 +2870,7 @@ pub fn updateDeclExports(
|
||||
|
||||
const gpa = self.base.allocator;
|
||||
|
||||
const decl = module.declPtr(decl_index);
|
||||
const decl = mod.declPtr(decl_index);
|
||||
const atom_index = try self.getOrCreateAtomForDecl(decl_index);
|
||||
const atom = self.getAtom(atom_index);
|
||||
const decl_sym = atom.getSymbol(self);
|
||||
@ -2881,10 +2882,10 @@ pub fn updateDeclExports(
|
||||
for (exports) |exp| {
|
||||
if (exp.options.section) |section_name| {
|
||||
if (!mem.eql(u8, section_name, ".text")) {
|
||||
try module.failed_exports.ensureUnusedCapacity(module.gpa, 1);
|
||||
module.failed_exports.putAssumeCapacityNoClobber(
|
||||
try mod.failed_exports.ensureUnusedCapacity(mod.gpa, 1);
|
||||
mod.failed_exports.putAssumeCapacityNoClobber(
|
||||
exp,
|
||||
try Module.ErrorMsg.create(self.base.allocator, decl.srcLoc(), "Unimplemented: ExportOptions.section", .{}),
|
||||
try Module.ErrorMsg.create(self.base.allocator, decl.srcLoc(mod), "Unimplemented: ExportOptions.section", .{}),
|
||||
);
|
||||
continue;
|
||||
}
|
||||
@ -2900,10 +2901,10 @@ pub fn updateDeclExports(
|
||||
},
|
||||
.Weak => elf.STB_WEAK,
|
||||
.LinkOnce => {
|
||||
try module.failed_exports.ensureUnusedCapacity(module.gpa, 1);
|
||||
module.failed_exports.putAssumeCapacityNoClobber(
|
||||
try mod.failed_exports.ensureUnusedCapacity(mod.gpa, 1);
|
||||
mod.failed_exports.putAssumeCapacityNoClobber(
|
||||
exp,
|
||||
try Module.ErrorMsg.create(self.base.allocator, decl.srcLoc(), "Unimplemented: GlobalLinkage.LinkOnce", .{}),
|
||||
try Module.ErrorMsg.create(self.base.allocator, decl.srcLoc(mod), "Unimplemented: GlobalLinkage.LinkOnce", .{}),
|
||||
);
|
||||
continue;
|
||||
},
|
||||
|
||||
@ -1847,18 +1847,18 @@ fn addStubEntry(self: *MachO, target: SymbolWithLoc) !void {
|
||||
self.markRelocsDirtyByTarget(target);
|
||||
}
|
||||
|
||||
pub fn updateFunc(self: *MachO, module: *Module, func: *Module.Fn, air: Air, liveness: Liveness) !void {
|
||||
pub fn updateFunc(self: *MachO, mod: *Module, func: *Module.Fn, air: Air, liveness: Liveness) !void {
|
||||
if (build_options.skip_non_native and builtin.object_format != .macho) {
|
||||
@panic("Attempted to compile for object format that was disabled by build configuration");
|
||||
}
|
||||
if (build_options.have_llvm) {
|
||||
if (self.llvm_object) |llvm_object| return llvm_object.updateFunc(module, func, air, liveness);
|
||||
if (self.llvm_object) |llvm_object| return llvm_object.updateFunc(mod, func, air, liveness);
|
||||
}
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
const decl_index = func.owner_decl;
|
||||
const decl = module.declPtr(decl_index);
|
||||
const decl = mod.declPtr(decl_index);
|
||||
|
||||
const atom_index = try self.getOrCreateAtomForDecl(decl_index);
|
||||
self.freeUnnamedConsts(decl_index);
|
||||
@ -1868,23 +1868,23 @@ pub fn updateFunc(self: *MachO, module: *Module, func: *Module.Fn, air: Air, liv
|
||||
defer code_buffer.deinit();
|
||||
|
||||
var decl_state = if (self.d_sym) |*d_sym|
|
||||
try d_sym.dwarf.initDeclState(module, decl_index)
|
||||
try d_sym.dwarf.initDeclState(mod, decl_index)
|
||||
else
|
||||
null;
|
||||
defer if (decl_state) |*ds| ds.deinit();
|
||||
|
||||
const res = if (decl_state) |*ds|
|
||||
try codegen.generateFunction(&self.base, decl.srcLoc(), func, air, liveness, &code_buffer, .{
|
||||
try codegen.generateFunction(&self.base, decl.srcLoc(mod), func, air, liveness, &code_buffer, .{
|
||||
.dwarf = ds,
|
||||
})
|
||||
else
|
||||
try codegen.generateFunction(&self.base, decl.srcLoc(), func, air, liveness, &code_buffer, .none);
|
||||
try codegen.generateFunction(&self.base, decl.srcLoc(mod), func, air, liveness, &code_buffer, .none);
|
||||
|
||||
var code = switch (res) {
|
||||
.ok => code_buffer.items,
|
||||
.fail => |em| {
|
||||
decl.analysis = .codegen_failure;
|
||||
try module.failed_decls.put(module.gpa, decl_index, em);
|
||||
try mod.failed_decls.put(mod.gpa, decl_index, em);
|
||||
return;
|
||||
},
|
||||
};
|
||||
@ -1893,7 +1893,7 @@ pub fn updateFunc(self: *MachO, module: *Module, func: *Module.Fn, air: Air, liv
|
||||
|
||||
if (decl_state) |*ds| {
|
||||
try self.d_sym.?.dwarf.commitDeclState(
|
||||
module,
|
||||
mod,
|
||||
decl_index,
|
||||
addr,
|
||||
self.getAtom(atom_index).size,
|
||||
@ -1903,7 +1903,7 @@ pub fn updateFunc(self: *MachO, module: *Module, func: *Module.Fn, air: Air, liv
|
||||
|
||||
// Since we updated the vaddr and the size, each corresponding export symbol also
|
||||
// needs to be updated.
|
||||
try self.updateDeclExports(module, decl_index, module.getDeclExports(decl_index));
|
||||
try self.updateDeclExports(mod, decl_index, mod.getDeclExports(decl_index));
|
||||
}
|
||||
|
||||
pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl_index: Module.Decl.Index) !u32 {
|
||||
@ -1912,15 +1912,15 @@ pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl_index: Modu
|
||||
var code_buffer = std.ArrayList(u8).init(gpa);
|
||||
defer code_buffer.deinit();
|
||||
|
||||
const module = self.base.options.module.?;
|
||||
const mod = self.base.options.module.?;
|
||||
const gop = try self.unnamed_const_atoms.getOrPut(gpa, decl_index);
|
||||
if (!gop.found_existing) {
|
||||
gop.value_ptr.* = .{};
|
||||
}
|
||||
const unnamed_consts = gop.value_ptr;
|
||||
|
||||
const decl = module.declPtr(decl_index);
|
||||
const decl_name = try decl.getFullyQualifiedName(module);
|
||||
const decl = mod.declPtr(decl_index);
|
||||
const decl_name = try decl.getFullyQualifiedName(mod);
|
||||
defer gpa.free(decl_name);
|
||||
|
||||
const name_str_index = blk: {
|
||||
@ -1935,20 +1935,19 @@ pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl_index: Modu
|
||||
|
||||
const atom_index = try self.createAtom();
|
||||
|
||||
const res = try codegen.generateSymbol(&self.base, decl.srcLoc(), typed_value, &code_buffer, .none, .{
|
||||
const res = try codegen.generateSymbol(&self.base, decl.srcLoc(mod), typed_value, &code_buffer, .none, .{
|
||||
.parent_atom_index = self.getAtom(atom_index).getSymbolIndex().?,
|
||||
});
|
||||
var code = switch (res) {
|
||||
.ok => code_buffer.items,
|
||||
.fail => |em| {
|
||||
decl.analysis = .codegen_failure;
|
||||
try module.failed_decls.put(module.gpa, decl_index, em);
|
||||
try mod.failed_decls.put(mod.gpa, decl_index, em);
|
||||
log.err("{s}", .{em.msg});
|
||||
return error.CodegenFail;
|
||||
},
|
||||
};
|
||||
|
||||
const mod = self.base.options.module.?;
|
||||
const required_alignment = typed_value.ty.abiAlignment(mod);
|
||||
const atom = self.getAtomPtr(atom_index);
|
||||
atom.size = code.len;
|
||||
@ -1972,17 +1971,17 @@ pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl_index: Modu
|
||||
return atom.getSymbolIndex().?;
|
||||
}
|
||||
|
||||
pub fn updateDecl(self: *MachO, module: *Module, decl_index: Module.Decl.Index) !void {
|
||||
pub fn updateDecl(self: *MachO, mod: *Module, decl_index: Module.Decl.Index) !void {
|
||||
if (build_options.skip_non_native and builtin.object_format != .macho) {
|
||||
@panic("Attempted to compile for object format that was disabled by build configuration");
|
||||
}
|
||||
if (build_options.have_llvm) {
|
||||
if (self.llvm_object) |llvm_object| return llvm_object.updateDecl(module, decl_index);
|
||||
if (self.llvm_object) |llvm_object| return llvm_object.updateDecl(mod, decl_index);
|
||||
}
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
const decl = module.declPtr(decl_index);
|
||||
const decl = mod.declPtr(decl_index);
|
||||
|
||||
if (decl.val.tag() == .extern_fn) {
|
||||
return; // TODO Should we do more when front-end analyzed extern decl?
|
||||
@ -1998,7 +1997,7 @@ pub fn updateDecl(self: *MachO, module: *Module, decl_index: Module.Decl.Index)
|
||||
payload.data.is_threadlocal and !self.base.options.single_threaded
|
||||
else
|
||||
false;
|
||||
if (is_threadlocal) return self.updateThreadlocalVariable(module, decl_index);
|
||||
if (is_threadlocal) return self.updateThreadlocalVariable(mod, decl_index);
|
||||
|
||||
const atom_index = try self.getOrCreateAtomForDecl(decl_index);
|
||||
const sym_index = self.getAtom(atom_index).getSymbolIndex().?;
|
||||
@ -2008,14 +2007,14 @@ pub fn updateDecl(self: *MachO, module: *Module, decl_index: Module.Decl.Index)
|
||||
defer code_buffer.deinit();
|
||||
|
||||
var decl_state: ?Dwarf.DeclState = if (self.d_sym) |*d_sym|
|
||||
try d_sym.dwarf.initDeclState(module, decl_index)
|
||||
try d_sym.dwarf.initDeclState(mod, decl_index)
|
||||
else
|
||||
null;
|
||||
defer if (decl_state) |*ds| ds.deinit();
|
||||
|
||||
const decl_val = if (decl.val.castTag(.variable)) |payload| payload.data.init else decl.val;
|
||||
const res = if (decl_state) |*ds|
|
||||
try codegen.generateSymbol(&self.base, decl.srcLoc(), .{
|
||||
try codegen.generateSymbol(&self.base, decl.srcLoc(mod), .{
|
||||
.ty = decl.ty,
|
||||
.val = decl_val,
|
||||
}, &code_buffer, .{
|
||||
@ -2024,7 +2023,7 @@ pub fn updateDecl(self: *MachO, module: *Module, decl_index: Module.Decl.Index)
|
||||
.parent_atom_index = sym_index,
|
||||
})
|
||||
else
|
||||
try codegen.generateSymbol(&self.base, decl.srcLoc(), .{
|
||||
try codegen.generateSymbol(&self.base, decl.srcLoc(mod), .{
|
||||
.ty = decl.ty,
|
||||
.val = decl_val,
|
||||
}, &code_buffer, .none, .{
|
||||
@ -2035,7 +2034,7 @@ pub fn updateDecl(self: *MachO, module: *Module, decl_index: Module.Decl.Index)
|
||||
.ok => code_buffer.items,
|
||||
.fail => |em| {
|
||||
decl.analysis = .codegen_failure;
|
||||
try module.failed_decls.put(module.gpa, decl_index, em);
|
||||
try mod.failed_decls.put(mod.gpa, decl_index, em);
|
||||
return;
|
||||
},
|
||||
};
|
||||
@ -2043,7 +2042,7 @@ pub fn updateDecl(self: *MachO, module: *Module, decl_index: Module.Decl.Index)
|
||||
|
||||
if (decl_state) |*ds| {
|
||||
try self.d_sym.?.dwarf.commitDeclState(
|
||||
module,
|
||||
mod,
|
||||
decl_index,
|
||||
addr,
|
||||
self.getAtom(atom_index).size,
|
||||
@ -2053,7 +2052,7 @@ pub fn updateDecl(self: *MachO, module: *Module, decl_index: Module.Decl.Index)
|
||||
|
||||
// Since we updated the vaddr and the size, each corresponding export symbol also
|
||||
// needs to be updated.
|
||||
try self.updateDeclExports(module, decl_index, module.getDeclExports(decl_index));
|
||||
try self.updateDeclExports(mod, decl_index, mod.getDeclExports(decl_index));
|
||||
}
|
||||
|
||||
fn updateLazySymbolAtom(
|
||||
@ -2082,8 +2081,8 @@ fn updateLazySymbolAtom(
|
||||
const atom = self.getAtomPtr(atom_index);
|
||||
const local_sym_index = atom.getSymbolIndex().?;
|
||||
|
||||
const src = if (sym.ty.getOwnerDeclOrNull()) |owner_decl|
|
||||
mod.declPtr(owner_decl).srcLoc()
|
||||
const src = if (sym.ty.getOwnerDeclOrNull(mod)) |owner_decl|
|
||||
mod.declPtr(owner_decl).srcLoc(mod)
|
||||
else
|
||||
Module.SrcLoc{
|
||||
.file_scope = undefined,
|
||||
@ -2127,7 +2126,8 @@ fn updateLazySymbolAtom(
|
||||
}
|
||||
|
||||
pub fn getOrCreateAtomForLazySymbol(self: *MachO, sym: File.LazySymbol) !Atom.Index {
|
||||
const gop = try self.lazy_syms.getOrPut(self.base.allocator, sym.getDecl());
|
||||
const mod = self.base.options.module.?;
|
||||
const gop = try self.lazy_syms.getOrPut(self.base.allocator, sym.getDecl(mod));
|
||||
errdefer _ = if (!gop.found_existing) self.lazy_syms.pop();
|
||||
if (!gop.found_existing) gop.value_ptr.* = .{};
|
||||
const metadata: struct { atom: *Atom.Index, state: *LazySymbolMetadata.State } = switch (sym.kind) {
|
||||
@ -2145,7 +2145,7 @@ pub fn getOrCreateAtomForLazySymbol(self: *MachO, sym: File.LazySymbol) !Atom.In
|
||||
metadata.state.* = .pending_flush;
|
||||
const atom = metadata.atom.*;
|
||||
// anyerror needs to be deferred until flushModule
|
||||
if (sym.getDecl() != .none) try self.updateLazySymbolAtom(sym, atom, switch (sym.kind) {
|
||||
if (sym.getDecl(mod) != .none) try self.updateLazySymbolAtom(sym, atom, switch (sym.kind) {
|
||||
.code => self.text_section_index.?,
|
||||
.const_data => self.data_const_section_index.?,
|
||||
});
|
||||
@ -2179,7 +2179,7 @@ fn updateThreadlocalVariable(self: *MachO, module: *Module, decl_index: Module.D
|
||||
const decl_metadata = self.decls.get(decl_index).?;
|
||||
const decl_val = decl.val.castTag(.variable).?.data.init;
|
||||
const res = if (decl_state) |*ds|
|
||||
try codegen.generateSymbol(&self.base, decl.srcLoc(), .{
|
||||
try codegen.generateSymbol(&self.base, decl.srcLoc(mod), .{
|
||||
.ty = decl.ty,
|
||||
.val = decl_val,
|
||||
}, &code_buffer, .{
|
||||
@ -2188,7 +2188,7 @@ fn updateThreadlocalVariable(self: *MachO, module: *Module, decl_index: Module.D
|
||||
.parent_atom_index = init_sym_index,
|
||||
})
|
||||
else
|
||||
try codegen.generateSymbol(&self.base, decl.srcLoc(), .{
|
||||
try codegen.generateSymbol(&self.base, decl.srcLoc(mod), .{
|
||||
.ty = decl.ty,
|
||||
.val = decl_val,
|
||||
}, &code_buffer, .none, .{
|
||||
@ -2379,7 +2379,7 @@ pub fn updateDeclLineNumber(self: *MachO, module: *Module, decl_index: Module.De
|
||||
|
||||
pub fn updateDeclExports(
|
||||
self: *MachO,
|
||||
module: *Module,
|
||||
mod: *Module,
|
||||
decl_index: Module.Decl.Index,
|
||||
exports: []const *Module.Export,
|
||||
) File.UpdateDeclExportsError!void {
|
||||
@ -2388,7 +2388,7 @@ pub fn updateDeclExports(
|
||||
}
|
||||
if (build_options.have_llvm) {
|
||||
if (self.llvm_object) |llvm_object|
|
||||
return llvm_object.updateDeclExports(module, decl_index, exports);
|
||||
return llvm_object.updateDeclExports(mod, decl_index, exports);
|
||||
}
|
||||
|
||||
const tracy = trace(@src());
|
||||
@ -2396,7 +2396,7 @@ pub fn updateDeclExports(
|
||||
|
||||
const gpa = self.base.allocator;
|
||||
|
||||
const decl = module.declPtr(decl_index);
|
||||
const decl = mod.declPtr(decl_index);
|
||||
const atom_index = try self.getOrCreateAtomForDecl(decl_index);
|
||||
const atom = self.getAtom(atom_index);
|
||||
const decl_sym = atom.getSymbol(self);
|
||||
@ -2410,12 +2410,12 @@ pub fn updateDeclExports(
|
||||
|
||||
if (exp.options.section) |section_name| {
|
||||
if (!mem.eql(u8, section_name, "__text")) {
|
||||
try module.failed_exports.putNoClobber(
|
||||
module.gpa,
|
||||
try mod.failed_exports.putNoClobber(
|
||||
mod.gpa,
|
||||
exp,
|
||||
try Module.ErrorMsg.create(
|
||||
gpa,
|
||||
decl.srcLoc(),
|
||||
decl.srcLoc(mod),
|
||||
"Unimplemented: ExportOptions.section",
|
||||
.{},
|
||||
),
|
||||
@ -2425,12 +2425,12 @@ pub fn updateDeclExports(
|
||||
}
|
||||
|
||||
if (exp.options.linkage == .LinkOnce) {
|
||||
try module.failed_exports.putNoClobber(
|
||||
module.gpa,
|
||||
try mod.failed_exports.putNoClobber(
|
||||
mod.gpa,
|
||||
exp,
|
||||
try Module.ErrorMsg.create(
|
||||
gpa,
|
||||
decl.srcLoc(),
|
||||
decl.srcLoc(mod),
|
||||
"Unimplemented: GlobalLinkage.LinkOnce",
|
||||
.{},
|
||||
),
|
||||
@ -2474,9 +2474,9 @@ pub fn updateDeclExports(
|
||||
// TODO: this needs rethinking
|
||||
const global = self.getGlobal(exp_name).?;
|
||||
if (sym_loc.sym_index != global.sym_index and global.file != null) {
|
||||
_ = try module.failed_exports.put(module.gpa, exp, try Module.ErrorMsg.create(
|
||||
_ = try mod.failed_exports.put(mod.gpa, exp, try Module.ErrorMsg.create(
|
||||
gpa,
|
||||
decl.srcLoc(),
|
||||
decl.srcLoc(mod),
|
||||
\\LinkError: symbol '{s}' defined multiple times
|
||||
,
|
||||
.{exp_name},
|
||||
|
||||
@ -213,14 +213,14 @@ fn putFn(self: *Plan9, decl_index: Module.Decl.Index, out: FnDeclOutput) !void {
|
||||
const gpa = self.base.allocator;
|
||||
const mod = self.base.options.module.?;
|
||||
const decl = mod.declPtr(decl_index);
|
||||
const fn_map_res = try self.fn_decl_table.getOrPut(gpa, decl.getFileScope());
|
||||
const fn_map_res = try self.fn_decl_table.getOrPut(gpa, decl.getFileScope(mod));
|
||||
if (fn_map_res.found_existing) {
|
||||
if (try fn_map_res.value_ptr.functions.fetchPut(gpa, decl_index, out)) |old_entry| {
|
||||
gpa.free(old_entry.value.code);
|
||||
gpa.free(old_entry.value.lineinfo);
|
||||
}
|
||||
} else {
|
||||
const file = decl.getFileScope();
|
||||
const file = decl.getFileScope(mod);
|
||||
const arena = self.path_arena.allocator();
|
||||
// each file gets a symbol
|
||||
fn_map_res.value_ptr.* = .{
|
||||
@ -276,13 +276,13 @@ fn addPathComponents(self: *Plan9, path: []const u8, a: *std.ArrayList(u8)) !voi
|
||||
}
|
||||
}
|
||||
|
||||
pub fn updateFunc(self: *Plan9, module: *Module, func: *Module.Fn, air: Air, liveness: Liveness) !void {
|
||||
pub fn updateFunc(self: *Plan9, mod: *Module, func: *Module.Fn, air: Air, liveness: Liveness) !void {
|
||||
if (build_options.skip_non_native and builtin.object_format != .plan9) {
|
||||
@panic("Attempted to compile for object format that was disabled by build configuration");
|
||||
}
|
||||
|
||||
const decl_index = func.owner_decl;
|
||||
const decl = module.declPtr(decl_index);
|
||||
const decl = mod.declPtr(decl_index);
|
||||
self.freeUnnamedConsts(decl_index);
|
||||
|
||||
_ = try self.seeDecl(decl_index);
|
||||
@ -298,7 +298,7 @@ pub fn updateFunc(self: *Plan9, module: *Module, func: *Module.Fn, air: Air, liv
|
||||
|
||||
const res = try codegen.generateFunction(
|
||||
&self.base,
|
||||
decl.srcLoc(),
|
||||
decl.srcLoc(mod),
|
||||
func,
|
||||
air,
|
||||
liveness,
|
||||
@ -316,7 +316,7 @@ pub fn updateFunc(self: *Plan9, module: *Module, func: *Module.Fn, air: Air, liv
|
||||
.ok => try code_buffer.toOwnedSlice(),
|
||||
.fail => |em| {
|
||||
decl.analysis = .codegen_failure;
|
||||
try module.failed_decls.put(module.gpa, decl_index, em);
|
||||
try mod.failed_decls.put(mod.gpa, decl_index, em);
|
||||
return;
|
||||
},
|
||||
};
|
||||
@ -366,7 +366,7 @@ pub fn lowerUnnamedConst(self: *Plan9, tv: TypedValue, decl_index: Module.Decl.I
|
||||
};
|
||||
self.syms.items[info.sym_index.?] = sym;
|
||||
|
||||
const res = try codegen.generateSymbol(&self.base, decl.srcLoc(), tv, &code_buffer, .{
|
||||
const res = try codegen.generateSymbol(&self.base, decl.srcLoc(mod), tv, &code_buffer, .{
|
||||
.none = {},
|
||||
}, .{
|
||||
.parent_atom_index = @enumToInt(decl_index),
|
||||
@ -388,8 +388,8 @@ pub fn lowerUnnamedConst(self: *Plan9, tv: TypedValue, decl_index: Module.Decl.I
|
||||
return @intCast(u32, info.got_index.?);
|
||||
}
|
||||
|
||||
pub fn updateDecl(self: *Plan9, module: *Module, decl_index: Module.Decl.Index) !void {
|
||||
const decl = module.declPtr(decl_index);
|
||||
pub fn updateDecl(self: *Plan9, mod: *Module, decl_index: Module.Decl.Index) !void {
|
||||
const decl = mod.declPtr(decl_index);
|
||||
|
||||
if (decl.val.tag() == .extern_fn) {
|
||||
return; // TODO Should we do more when front-end analyzed extern decl?
|
||||
@ -409,7 +409,7 @@ pub fn updateDecl(self: *Plan9, module: *Module, decl_index: Module.Decl.Index)
|
||||
defer code_buffer.deinit();
|
||||
const decl_val = if (decl.val.castTag(.variable)) |payload| payload.data.init else decl.val;
|
||||
// TODO we need the symbol index for symbol in the table of locals for the containing atom
|
||||
const res = try codegen.generateSymbol(&self.base, decl.srcLoc(), .{
|
||||
const res = try codegen.generateSymbol(&self.base, decl.srcLoc(mod), .{
|
||||
.ty = decl.ty,
|
||||
.val = decl_val,
|
||||
}, &code_buffer, .{ .none = {} }, .{
|
||||
@ -419,7 +419,7 @@ pub fn updateDecl(self: *Plan9, module: *Module, decl_index: Module.Decl.Index)
|
||||
.ok => code_buffer.items,
|
||||
.fail => |em| {
|
||||
decl.analysis = .codegen_failure;
|
||||
try module.failed_decls.put(module.gpa, decl_index, em);
|
||||
try mod.failed_decls.put(mod.gpa, decl_index, em);
|
||||
return;
|
||||
},
|
||||
};
|
||||
@ -707,7 +707,7 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
|
||||
const code = blk: {
|
||||
const is_fn = source_decl.ty.zigTypeTag(mod) == .Fn;
|
||||
if (is_fn) {
|
||||
const table = self.fn_decl_table.get(source_decl.getFileScope()).?.functions;
|
||||
const table = self.fn_decl_table.get(source_decl.getFileScope(mod)).?.functions;
|
||||
const output = table.get(source_decl_index).?;
|
||||
break :blk output.code;
|
||||
} else {
|
||||
@ -729,7 +729,7 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
|
||||
}
|
||||
fn addDeclExports(
|
||||
self: *Plan9,
|
||||
module: *Module,
|
||||
mod: *Module,
|
||||
decl_index: Module.Decl.Index,
|
||||
exports: []const *Module.Export,
|
||||
) !void {
|
||||
@ -740,9 +740,9 @@ fn addDeclExports(
|
||||
// plan9 does not support custom sections
|
||||
if (exp.options.section) |section_name| {
|
||||
if (!mem.eql(u8, section_name, ".text") or !mem.eql(u8, section_name, ".data")) {
|
||||
try module.failed_exports.put(module.gpa, exp, try Module.ErrorMsg.create(
|
||||
try mod.failed_exports.put(mod.gpa, exp, try Module.ErrorMsg.create(
|
||||
self.base.allocator,
|
||||
module.declPtr(decl_index).srcLoc(),
|
||||
mod.declPtr(decl_index).srcLoc(mod),
|
||||
"plan9 does not support extra sections",
|
||||
.{},
|
||||
));
|
||||
@ -773,7 +773,7 @@ pub fn freeDecl(self: *Plan9, decl_index: Module.Decl.Index) void {
|
||||
const decl = mod.declPtr(decl_index);
|
||||
const is_fn = (decl.val.tag() == .function);
|
||||
if (is_fn) {
|
||||
var symidx_and_submap = self.fn_decl_table.get(decl.getFileScope()).?;
|
||||
var symidx_and_submap = self.fn_decl_table.get(decl.getFileScope(mod)).?;
|
||||
var submap = symidx_and_submap.functions;
|
||||
if (submap.fetchSwapRemove(decl_index)) |removed_entry| {
|
||||
self.base.allocator.free(removed_entry.value.code);
|
||||
|
||||
@ -1348,7 +1348,7 @@ pub fn updateFunc(wasm: *Wasm, mod: *Module, func: *Module.Fn, air: Air, livenes
|
||||
defer code_writer.deinit();
|
||||
// const result = try codegen.generateFunction(
|
||||
// &wasm.base,
|
||||
// decl.srcLoc(),
|
||||
// decl.srcLoc(mod),
|
||||
// func,
|
||||
// air,
|
||||
// liveness,
|
||||
@ -1357,7 +1357,7 @@ pub fn updateFunc(wasm: *Wasm, mod: *Module, func: *Module.Fn, air: Air, livenes
|
||||
// );
|
||||
const result = try codegen.generateFunction(
|
||||
&wasm.base,
|
||||
decl.srcLoc(),
|
||||
decl.srcLoc(mod),
|
||||
func,
|
||||
air,
|
||||
liveness,
|
||||
@ -1425,7 +1425,7 @@ pub fn updateDecl(wasm: *Wasm, mod: *Module, decl_index: Module.Decl.Index) !voi
|
||||
|
||||
const res = try codegen.generateSymbol(
|
||||
&wasm.base,
|
||||
decl.srcLoc(),
|
||||
decl.srcLoc(mod),
|
||||
.{ .ty = decl.ty, .val = val },
|
||||
&code_writer,
|
||||
.none,
|
||||
@ -1554,7 +1554,7 @@ pub fn lowerUnnamedConst(wasm: *Wasm, tv: TypedValue, decl_index: Module.Decl.In
|
||||
|
||||
const result = try codegen.generateSymbol(
|
||||
&wasm.base,
|
||||
decl.srcLoc(),
|
||||
decl.srcLoc(mod),
|
||||
tv,
|
||||
&value_bytes,
|
||||
.none,
|
||||
@ -1693,7 +1693,7 @@ pub fn updateDeclExports(
|
||||
if (exp.options.section) |section| {
|
||||
try mod.failed_exports.putNoClobber(mod.gpa, exp, try Module.ErrorMsg.create(
|
||||
mod.gpa,
|
||||
decl.srcLoc(),
|
||||
decl.srcLoc(mod),
|
||||
"Unimplemented: ExportOptions.section '{s}'",
|
||||
.{section},
|
||||
));
|
||||
@ -1712,7 +1712,7 @@ pub fn updateDeclExports(
|
||||
if (!exp_is_weak and !existing_sym.isWeak()) {
|
||||
try mod.failed_exports.put(mod.gpa, exp, try Module.ErrorMsg.create(
|
||||
mod.gpa,
|
||||
decl.srcLoc(),
|
||||
decl.srcLoc(mod),
|
||||
\\LinkError: symbol '{s}' defined multiple times
|
||||
\\ first definition in '{s}'
|
||||
\\ next definition in '{s}'
|
||||
@ -1745,7 +1745,7 @@ pub fn updateDeclExports(
|
||||
.LinkOnce => {
|
||||
try mod.failed_exports.putNoClobber(mod.gpa, exp, try Module.ErrorMsg.create(
|
||||
mod.gpa,
|
||||
decl.srcLoc(),
|
||||
decl.srcLoc(mod),
|
||||
"Unimplemented: LinkOnce",
|
||||
.{},
|
||||
));
|
||||
|
||||
225
src/type.zig
225
src/type.zig
@ -42,8 +42,6 @@ pub const Type = struct {
|
||||
.error_set_merged,
|
||||
=> return .ErrorSet,
|
||||
|
||||
.@"opaque" => return .Opaque,
|
||||
|
||||
.function => return .Fn,
|
||||
|
||||
.array,
|
||||
@ -87,6 +85,7 @@ pub const Type = struct {
|
||||
.error_union_type => return .ErrorUnion,
|
||||
.struct_type => return .Struct,
|
||||
.union_type => return .Union,
|
||||
.opaque_type => return .Opaque,
|
||||
.simple_type => |s| switch (s) {
|
||||
.f16,
|
||||
.f32,
|
||||
@ -361,12 +360,6 @@ pub const Type = struct {
|
||||
return true;
|
||||
},
|
||||
|
||||
.@"opaque" => {
|
||||
const opaque_obj_a = a.castTag(.@"opaque").?.data;
|
||||
const opaque_obj_b = (b.castTag(.@"opaque") orelse return false).data;
|
||||
return opaque_obj_a == opaque_obj_b;
|
||||
},
|
||||
|
||||
.function => {
|
||||
if (b.zigTypeTag(mod) != .Fn) return false;
|
||||
|
||||
@ -649,12 +642,6 @@ pub const Type = struct {
|
||||
std.hash.autoHash(hasher, ies);
|
||||
},
|
||||
|
||||
.@"opaque" => {
|
||||
std.hash.autoHash(hasher, std.builtin.TypeId.Opaque);
|
||||
const opaque_obj = ty.castTag(.@"opaque").?.data;
|
||||
std.hash.autoHash(hasher, opaque_obj);
|
||||
},
|
||||
|
||||
.function => {
|
||||
std.hash.autoHash(hasher, std.builtin.TypeId.Fn);
|
||||
|
||||
@ -974,7 +961,6 @@ pub const Type = struct {
|
||||
.enum_simple => return self.copyPayloadShallow(allocator, Payload.EnumSimple),
|
||||
.enum_numbered => return self.copyPayloadShallow(allocator, Payload.EnumNumbered),
|
||||
.enum_full, .enum_nonexhaustive => return self.copyPayloadShallow(allocator, Payload.EnumFull),
|
||||
.@"opaque" => return self.copyPayloadShallow(allocator, Payload.Opaque),
|
||||
}
|
||||
}
|
||||
|
||||
@ -1079,12 +1065,6 @@ pub const Type = struct {
|
||||
@tagName(t), enum_numbered.owner_decl,
|
||||
});
|
||||
},
|
||||
.@"opaque" => {
|
||||
const opaque_obj = ty.castTag(.@"opaque").?.data;
|
||||
return writer.print("({s} decl={d})", .{
|
||||
@tagName(t), opaque_obj.owner_decl,
|
||||
});
|
||||
},
|
||||
|
||||
.function => {
|
||||
const payload = ty.castTag(.function).?.data;
|
||||
@ -1303,11 +1283,6 @@ pub const Type = struct {
|
||||
const decl = mod.declPtr(enum_numbered.owner_decl);
|
||||
try decl.renderFullyQualifiedName(mod, writer);
|
||||
},
|
||||
.@"opaque" => {
|
||||
const opaque_obj = ty.cast(Payload.Opaque).?.data;
|
||||
const decl = mod.declPtr(opaque_obj.owner_decl);
|
||||
try decl.renderFullyQualifiedName(mod, writer);
|
||||
},
|
||||
|
||||
.error_set_inferred => {
|
||||
const func = ty.castTag(.error_set_inferred).?.data.func;
|
||||
@ -1575,6 +1550,10 @@ pub const Type = struct {
|
||||
.simple_type => |s| return writer.writeAll(@tagName(s)),
|
||||
.struct_type => @panic("TODO"),
|
||||
.union_type => @panic("TODO"),
|
||||
.opaque_type => |opaque_type| {
|
||||
const decl = mod.declPtr(opaque_type.decl);
|
||||
try decl.renderFullyQualifiedName(mod, writer);
|
||||
},
|
||||
|
||||
// values, not types
|
||||
.simple_value => unreachable,
|
||||
@ -1622,7 +1601,6 @@ pub const Type = struct {
|
||||
.none => switch (ty.tag()) {
|
||||
.error_set_inferred,
|
||||
|
||||
.@"opaque",
|
||||
.error_set_single,
|
||||
.error_union,
|
||||
.error_set,
|
||||
@ -1759,8 +1737,8 @@ pub const Type = struct {
|
||||
.inferred_alloc_const => unreachable,
|
||||
.inferred_alloc_mut => unreachable,
|
||||
},
|
||||
else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
|
||||
.int_type => |int_type| return int_type.bits != 0,
|
||||
else => return switch (mod.intern_pool.indexToKey(ty.ip_index)) {
|
||||
.int_type => |int_type| int_type.bits != 0,
|
||||
.ptr_type => |ptr_type| {
|
||||
// Pointers to zero-bit types still have a runtime address; however, pointers
|
||||
// to comptime-only types do not, with the exception of function pointers.
|
||||
@ -1797,7 +1775,7 @@ pub const Type = struct {
|
||||
}
|
||||
},
|
||||
.error_union_type => @panic("TODO"),
|
||||
.simple_type => |t| return switch (t) {
|
||||
.simple_type => |t| switch (t) {
|
||||
.f16,
|
||||
.f32,
|
||||
.f64,
|
||||
@ -1848,6 +1826,7 @@ pub const Type = struct {
|
||||
},
|
||||
.struct_type => @panic("TODO"),
|
||||
.union_type => @panic("TODO"),
|
||||
.opaque_type => true,
|
||||
|
||||
// values, not types
|
||||
.simple_value => unreachable,
|
||||
@ -1876,7 +1855,6 @@ pub const Type = struct {
|
||||
.error_set_single,
|
||||
.error_set_inferred,
|
||||
.error_set_merged,
|
||||
.@"opaque",
|
||||
// These are function bodies, not function pointers.
|
||||
.function,
|
||||
.enum_simple,
|
||||
@ -1960,6 +1938,7 @@ pub const Type = struct {
|
||||
},
|
||||
.struct_type => @panic("TODO"),
|
||||
.union_type => @panic("TODO"),
|
||||
.opaque_type => false,
|
||||
|
||||
// values, not types
|
||||
.simple_value => unreachable,
|
||||
@ -2144,8 +2123,6 @@ pub const Type = struct {
|
||||
switch (ty.ip_index) {
|
||||
.empty_struct_type => return AbiAlignmentAdvanced{ .scalar = 0 },
|
||||
.none => switch (ty.tag()) {
|
||||
.@"opaque" => return AbiAlignmentAdvanced{ .scalar = 1 },
|
||||
|
||||
// represents machine code; not a pointer
|
||||
.function => {
|
||||
const alignment = ty.castTag(.function).?.data.alignment;
|
||||
@ -2362,6 +2339,7 @@ pub const Type = struct {
|
||||
},
|
||||
.struct_type => @panic("TODO"),
|
||||
.union_type => @panic("TODO"),
|
||||
.opaque_type => return AbiAlignmentAdvanced{ .scalar = 1 },
|
||||
|
||||
// values, not types
|
||||
.simple_value => unreachable,
|
||||
@ -2536,7 +2514,6 @@ pub const Type = struct {
|
||||
|
||||
.none => switch (ty.tag()) {
|
||||
.function => unreachable, // represents machine code; not a pointer
|
||||
.@"opaque" => unreachable, // no size available
|
||||
.inferred_alloc_const => unreachable,
|
||||
.inferred_alloc_mut => unreachable,
|
||||
|
||||
@ -2777,6 +2754,7 @@ pub const Type = struct {
|
||||
},
|
||||
.struct_type => @panic("TODO"),
|
||||
.union_type => @panic("TODO"),
|
||||
.opaque_type => unreachable, // no size available
|
||||
|
||||
// values, not types
|
||||
.simple_value => unreachable,
|
||||
@ -2948,6 +2926,7 @@ pub const Type = struct {
|
||||
},
|
||||
.struct_type => @panic("TODO"),
|
||||
.union_type => @panic("TODO"),
|
||||
.opaque_type => unreachable,
|
||||
|
||||
// values, not types
|
||||
.simple_value => unreachable,
|
||||
@ -2965,7 +2944,6 @@ pub const Type = struct {
|
||||
.empty_struct => unreachable,
|
||||
.inferred_alloc_const => unreachable,
|
||||
.inferred_alloc_mut => unreachable,
|
||||
.@"opaque" => unreachable,
|
||||
|
||||
.@"struct" => {
|
||||
const struct_obj = ty.castTag(.@"struct").?.data;
|
||||
@ -3806,6 +3784,7 @@ pub const Type = struct {
|
||||
.simple_type => unreachable, // handled via Index enum tag above
|
||||
.struct_type => @panic("TODO"),
|
||||
.union_type => unreachable,
|
||||
.opaque_type => unreachable,
|
||||
|
||||
// values, not types
|
||||
.simple_value => unreachable,
|
||||
@ -4004,7 +3983,6 @@ pub const Type = struct {
|
||||
.function,
|
||||
.array_sentinel,
|
||||
.error_set_inferred,
|
||||
.@"opaque",
|
||||
.anyframe_T,
|
||||
.pointer,
|
||||
=> return null,
|
||||
@ -4182,6 +4160,7 @@ pub const Type = struct {
|
||||
},
|
||||
.struct_type => @panic("TODO"),
|
||||
.union_type => @panic("TODO"),
|
||||
.opaque_type => return null,
|
||||
|
||||
// values, not types
|
||||
.simple_value => unreachable,
|
||||
@ -4208,7 +4187,6 @@ pub const Type = struct {
|
||||
.error_set_single,
|
||||
.error_set_inferred,
|
||||
.error_set_merged,
|
||||
.@"opaque",
|
||||
.enum_simple,
|
||||
=> false,
|
||||
|
||||
@ -4350,6 +4328,7 @@ pub const Type = struct {
|
||||
},
|
||||
.struct_type => @panic("TODO"),
|
||||
.union_type => @panic("TODO"),
|
||||
.opaque_type => false,
|
||||
|
||||
// values, not types
|
||||
.simple_value => unreachable,
|
||||
@ -4399,21 +4378,31 @@ pub const Type = struct {
|
||||
}
|
||||
|
||||
/// Returns null if the type has no namespace.
|
||||
pub fn getNamespace(self: Type) ?*Module.Namespace {
|
||||
return switch (self.tag()) {
|
||||
.@"struct" => &self.castTag(.@"struct").?.data.namespace,
|
||||
.enum_full => &self.castTag(.enum_full).?.data.namespace,
|
||||
.enum_nonexhaustive => &self.castTag(.enum_nonexhaustive).?.data.namespace,
|
||||
.empty_struct => self.castTag(.empty_struct).?.data,
|
||||
.@"opaque" => &self.castTag(.@"opaque").?.data.namespace,
|
||||
.@"union" => &self.castTag(.@"union").?.data.namespace,
|
||||
.union_safety_tagged => &self.castTag(.union_safety_tagged).?.data.namespace,
|
||||
.union_tagged => &self.castTag(.union_tagged).?.data.namespace,
|
||||
pub fn getNamespaceIndex(ty: Type, mod: *Module) Module.Namespace.OptionalIndex {
|
||||
return switch (ty.ip_index) {
|
||||
.none => switch (ty.tag()) {
|
||||
.@"struct" => ty.castTag(.@"struct").?.data.namespace.toOptional(),
|
||||
.enum_full => ty.castTag(.enum_full).?.data.namespace.toOptional(),
|
||||
.enum_nonexhaustive => ty.castTag(.enum_nonexhaustive).?.data.namespace.toOptional(),
|
||||
.empty_struct => @panic("TODO"),
|
||||
.@"union" => ty.castTag(.@"union").?.data.namespace.toOptional(),
|
||||
.union_safety_tagged => ty.castTag(.union_safety_tagged).?.data.namespace.toOptional(),
|
||||
.union_tagged => ty.castTag(.union_tagged).?.data.namespace.toOptional(),
|
||||
|
||||
else => null,
|
||||
else => .none,
|
||||
},
|
||||
else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
|
||||
.opaque_type => |opaque_type| opaque_type.namespace.toOptional(),
|
||||
else => .none,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/// Returns null if the type has no namespace.
|
||||
pub fn getNamespace(ty: Type, mod: *Module) ?*Module.Namespace {
|
||||
return if (getNamespaceIndex(ty, mod).unwrap()) |i| mod.namespacePtr(i) else null;
|
||||
}
|
||||
|
||||
// Works for vectors and vectors of integers.
|
||||
pub fn minInt(ty: Type, arena: Allocator, mod: *Module) !Value {
|
||||
const scalar = try minIntScalar(ty.scalarType(mod), mod);
|
||||
@ -4911,78 +4900,81 @@ pub const Type = struct {
|
||||
}
|
||||
|
||||
pub fn declSrcLocOrNull(ty: Type, mod: *Module) ?Module.SrcLoc {
|
||||
if (ty.ip_index != .none) switch (mod.intern_pool.indexToKey(ty.ip_index)) {
|
||||
.struct_type => @panic("TODO"),
|
||||
.union_type => @panic("TODO"),
|
||||
else => return null,
|
||||
};
|
||||
switch (ty.tag()) {
|
||||
.enum_full, .enum_nonexhaustive => {
|
||||
const enum_full = ty.cast(Payload.EnumFull).?.data;
|
||||
return enum_full.srcLoc(mod);
|
||||
},
|
||||
.enum_numbered => {
|
||||
const enum_numbered = ty.castTag(.enum_numbered).?.data;
|
||||
return enum_numbered.srcLoc(mod);
|
||||
},
|
||||
.enum_simple => {
|
||||
const enum_simple = ty.castTag(.enum_simple).?.data;
|
||||
return enum_simple.srcLoc(mod);
|
||||
},
|
||||
.@"struct" => {
|
||||
const struct_obj = ty.castTag(.@"struct").?.data;
|
||||
return struct_obj.srcLoc(mod);
|
||||
},
|
||||
.error_set => {
|
||||
const error_set = ty.castTag(.error_set).?.data;
|
||||
return error_set.srcLoc(mod);
|
||||
},
|
||||
.@"union", .union_safety_tagged, .union_tagged => {
|
||||
const union_obj = ty.cast(Payload.Union).?.data;
|
||||
return union_obj.srcLoc(mod);
|
||||
},
|
||||
.@"opaque" => {
|
||||
const opaque_obj = ty.cast(Payload.Opaque).?.data;
|
||||
return opaque_obj.srcLoc(mod);
|
||||
},
|
||||
switch (ty.ip_index) {
|
||||
.none => switch (ty.tag()) {
|
||||
.enum_full, .enum_nonexhaustive => {
|
||||
const enum_full = ty.cast(Payload.EnumFull).?.data;
|
||||
return enum_full.srcLoc(mod);
|
||||
},
|
||||
.enum_numbered => {
|
||||
const enum_numbered = ty.castTag(.enum_numbered).?.data;
|
||||
return enum_numbered.srcLoc(mod);
|
||||
},
|
||||
.enum_simple => {
|
||||
const enum_simple = ty.castTag(.enum_simple).?.data;
|
||||
return enum_simple.srcLoc(mod);
|
||||
},
|
||||
.@"struct" => {
|
||||
const struct_obj = ty.castTag(.@"struct").?.data;
|
||||
return struct_obj.srcLoc(mod);
|
||||
},
|
||||
.error_set => {
|
||||
const error_set = ty.castTag(.error_set).?.data;
|
||||
return error_set.srcLoc(mod);
|
||||
},
|
||||
.@"union", .union_safety_tagged, .union_tagged => {
|
||||
const union_obj = ty.cast(Payload.Union).?.data;
|
||||
return union_obj.srcLoc(mod);
|
||||
},
|
||||
|
||||
else => return null,
|
||||
else => return null,
|
||||
},
|
||||
else => return switch (mod.intern_pool.indexToKey(ty.ip_index)) {
|
||||
.struct_type => @panic("TODO"),
|
||||
.union_type => @panic("TODO"),
|
||||
.opaque_type => |opaque_type| mod.opaqueSrcLoc(opaque_type),
|
||||
else => null,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn getOwnerDecl(ty: Type) Module.Decl.Index {
|
||||
return ty.getOwnerDeclOrNull() orelse unreachable;
|
||||
pub fn getOwnerDecl(ty: Type, mod: *Module) Module.Decl.Index {
|
||||
return ty.getOwnerDeclOrNull(mod) orelse unreachable;
|
||||
}
|
||||
|
||||
pub fn getOwnerDeclOrNull(ty: Type) ?Module.Decl.Index {
|
||||
switch (ty.tag()) {
|
||||
.enum_full, .enum_nonexhaustive => {
|
||||
const enum_full = ty.cast(Payload.EnumFull).?.data;
|
||||
return enum_full.owner_decl;
|
||||
},
|
||||
.enum_numbered => return ty.castTag(.enum_numbered).?.data.owner_decl,
|
||||
.enum_simple => {
|
||||
const enum_simple = ty.castTag(.enum_simple).?.data;
|
||||
return enum_simple.owner_decl;
|
||||
},
|
||||
.@"struct" => {
|
||||
const struct_obj = ty.castTag(.@"struct").?.data;
|
||||
return struct_obj.owner_decl;
|
||||
},
|
||||
.error_set => {
|
||||
const error_set = ty.castTag(.error_set).?.data;
|
||||
return error_set.owner_decl;
|
||||
},
|
||||
.@"union", .union_safety_tagged, .union_tagged => {
|
||||
const union_obj = ty.cast(Payload.Union).?.data;
|
||||
return union_obj.owner_decl;
|
||||
},
|
||||
.@"opaque" => {
|
||||
const opaque_obj = ty.cast(Payload.Opaque).?.data;
|
||||
return opaque_obj.owner_decl;
|
||||
},
|
||||
pub fn getOwnerDeclOrNull(ty: Type, mod: *Module) ?Module.Decl.Index {
|
||||
switch (ty.ip_index) {
|
||||
.none => switch (ty.tag()) {
|
||||
.enum_full, .enum_nonexhaustive => {
|
||||
const enum_full = ty.cast(Payload.EnumFull).?.data;
|
||||
return enum_full.owner_decl;
|
||||
},
|
||||
.enum_numbered => return ty.castTag(.enum_numbered).?.data.owner_decl,
|
||||
.enum_simple => {
|
||||
const enum_simple = ty.castTag(.enum_simple).?.data;
|
||||
return enum_simple.owner_decl;
|
||||
},
|
||||
.@"struct" => {
|
||||
const struct_obj = ty.castTag(.@"struct").?.data;
|
||||
return struct_obj.owner_decl;
|
||||
},
|
||||
.error_set => {
|
||||
const error_set = ty.castTag(.error_set).?.data;
|
||||
return error_set.owner_decl;
|
||||
},
|
||||
.@"union", .union_safety_tagged, .union_tagged => {
|
||||
const union_obj = ty.cast(Payload.Union).?.data;
|
||||
return union_obj.owner_decl;
|
||||
},
|
||||
|
||||
else => return null,
|
||||
else => return null,
|
||||
},
|
||||
else => return switch (mod.intern_pool.indexToKey(ty.ip_index)) {
|
||||
.struct_type => @panic("TODO"),
|
||||
.union_type => @panic("TODO"),
|
||||
.opaque_type => |opaque_type| opaque_type.decl,
|
||||
else => null,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@ -5022,7 +5014,6 @@ pub const Type = struct {
|
||||
error_set_inferred,
|
||||
error_set_merged,
|
||||
empty_struct,
|
||||
@"opaque",
|
||||
@"struct",
|
||||
@"union",
|
||||
union_safety_tagged,
|
||||
@ -5055,7 +5046,6 @@ pub const Type = struct {
|
||||
.function => Payload.Function,
|
||||
.error_union => Payload.ErrorUnion,
|
||||
.error_set_single => Payload.Name,
|
||||
.@"opaque" => Payload.Opaque,
|
||||
.@"struct" => Payload.Struct,
|
||||
.@"union", .union_safety_tagged, .union_tagged => Payload.Union,
|
||||
.enum_full, .enum_nonexhaustive => Payload.EnumFull,
|
||||
@ -5336,11 +5326,6 @@ pub const Type = struct {
|
||||
data: *Module.Namespace,
|
||||
};
|
||||
|
||||
pub const Opaque = struct {
|
||||
base: Payload = .{ .tag = .@"opaque" },
|
||||
data: *Module.Opaque,
|
||||
};
|
||||
|
||||
pub const Struct = struct {
|
||||
base: Payload = .{ .tag = .@"struct" },
|
||||
data: *Module.Struct,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user