mirror of
https://github.com/ziglang/zig.git
synced 2025-01-10 20:21:16 +00:00
Zcu: pass PerThread
to intern pool string functions
This commit is contained in:
parent
525f341f33
commit
ca02266157
@ -29,8 +29,6 @@ const wasi_libc = @import("wasi_libc.zig");
|
||||
const fatal = @import("main.zig").fatal;
|
||||
const clangMain = @import("main.zig").clangMain;
|
||||
const Zcu = @import("Zcu.zig");
|
||||
/// Deprecated; use `Zcu`.
|
||||
const Module = Zcu;
|
||||
const Sema = @import("Sema.zig");
|
||||
const InternPool = @import("InternPool.zig");
|
||||
const Cache = std.Build.Cache;
|
||||
@ -50,7 +48,7 @@ gpa: Allocator,
|
||||
arena: Allocator,
|
||||
/// Not every Compilation compiles .zig code! For example you could do `zig build-exe foo.o`.
|
||||
/// TODO: rename to zcu: ?*Zcu
|
||||
module: ?*Module,
|
||||
module: ?*Zcu,
|
||||
/// Contains different state depending on whether the Compilation uses
|
||||
/// incremental or whole cache mode.
|
||||
cache_use: CacheUse,
|
||||
@ -120,7 +118,7 @@ astgen_work_queue: std.fifo.LinearFifo(Zcu.File.Index, .Dynamic),
|
||||
/// These jobs are to inspect the file system stat() and if the embedded file has changed
|
||||
/// on disk, mark the corresponding Decl outdated and queue up an `analyze_decl`
|
||||
/// task for it.
|
||||
embed_file_work_queue: std.fifo.LinearFifo(*Module.EmbedFile, .Dynamic),
|
||||
embed_file_work_queue: std.fifo.LinearFifo(*Zcu.EmbedFile, .Dynamic),
|
||||
|
||||
/// The ErrorMsg memory is owned by the `CObject`, using Compilation's general purpose allocator.
|
||||
/// This data is accessed by multiple threads and is protected by `mutex`.
|
||||
@ -252,7 +250,7 @@ pub const Emit = struct {
|
||||
};
|
||||
|
||||
pub const default_stack_protector_buffer_size = target_util.default_stack_protector_buffer_size;
|
||||
pub const SemaError = Module.SemaError;
|
||||
pub const SemaError = Zcu.SemaError;
|
||||
|
||||
pub const CRTFile = struct {
|
||||
lock: Cache.Lock,
|
||||
@ -1138,7 +1136,7 @@ pub const CreateOptions = struct {
|
||||
pdb_source_path: ?[]const u8 = null,
|
||||
/// (Windows) PDB output path
|
||||
pdb_out_path: ?[]const u8 = null,
|
||||
error_limit: ?Compilation.Module.ErrorInt = null,
|
||||
error_limit: ?Zcu.ErrorInt = null,
|
||||
global_cc_argv: []const []const u8 = &.{},
|
||||
|
||||
pub const Entry = link.File.OpenOptions.Entry;
|
||||
@ -1344,7 +1342,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
|
||||
|
||||
const main_mod = options.main_mod orelse options.root_mod;
|
||||
const comp = try arena.create(Compilation);
|
||||
const opt_zcu: ?*Module = if (have_zcu) blk: {
|
||||
const opt_zcu: ?*Zcu = if (have_zcu) blk: {
|
||||
// Pre-open the directory handles for cached ZIR code so that it does not need
|
||||
// to redundantly happen for each AstGen operation.
|
||||
const zir_sub_dir = "z";
|
||||
@ -1362,8 +1360,8 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
|
||||
.path = try options.global_cache_directory.join(arena, &[_][]const u8{zir_sub_dir}),
|
||||
};
|
||||
|
||||
const emit_h: ?*Module.GlobalEmitH = if (options.emit_h) |loc| eh: {
|
||||
const eh = try arena.create(Module.GlobalEmitH);
|
||||
const emit_h: ?*Zcu.GlobalEmitH = if (options.emit_h) |loc| eh: {
|
||||
const eh = try arena.create(Zcu.GlobalEmitH);
|
||||
eh.* = .{ .loc = loc };
|
||||
break :eh eh;
|
||||
} else null;
|
||||
@ -1386,7 +1384,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
|
||||
.builtin_modules = null, // `builtin_mod` is set
|
||||
});
|
||||
|
||||
const zcu = try arena.create(Module);
|
||||
const zcu = try arena.create(Zcu);
|
||||
zcu.* = .{
|
||||
.gpa = gpa,
|
||||
.comp = comp,
|
||||
@ -1434,7 +1432,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
|
||||
.c_object_work_queue = std.fifo.LinearFifo(*CObject, .Dynamic).init(gpa),
|
||||
.win32_resource_work_queue = if (build_options.only_core_functionality) {} else std.fifo.LinearFifo(*Win32Resource, .Dynamic).init(gpa),
|
||||
.astgen_work_queue = std.fifo.LinearFifo(Zcu.File.Index, .Dynamic).init(gpa),
|
||||
.embed_file_work_queue = std.fifo.LinearFifo(*Module.EmbedFile, .Dynamic).init(gpa),
|
||||
.embed_file_work_queue = std.fifo.LinearFifo(*Zcu.EmbedFile, .Dynamic).init(gpa),
|
||||
.c_source_files = options.c_source_files,
|
||||
.rc_source_files = options.rc_source_files,
|
||||
.cache_parent = cache,
|
||||
@ -2626,7 +2624,7 @@ fn reportMultiModuleErrors(zcu: *Zcu) !void {
|
||||
var num_errors: u32 = 0;
|
||||
const max_errors = 5;
|
||||
// Attach the "some omitted" note to the final error message
|
||||
var last_err: ?*Module.ErrorMsg = null;
|
||||
var last_err: ?*Zcu.ErrorMsg = null;
|
||||
|
||||
for (zcu.import_table.values(), 0..) |file, file_index_usize| {
|
||||
if (!file.multi_pkg) continue;
|
||||
@ -2642,13 +2640,13 @@ fn reportMultiModuleErrors(zcu: *Zcu) !void {
|
||||
const omitted = file.references.items.len -| max_notes;
|
||||
const num_notes = file.references.items.len - omitted;
|
||||
|
||||
const notes = try gpa.alloc(Module.ErrorMsg, if (omitted > 0) num_notes + 1 else num_notes);
|
||||
const notes = try gpa.alloc(Zcu.ErrorMsg, if (omitted > 0) num_notes + 1 else num_notes);
|
||||
errdefer gpa.free(notes);
|
||||
|
||||
for (notes[0..num_notes], file.references.items[0..num_notes], 0..) |*note, ref, i| {
|
||||
errdefer for (notes[0..i]) |*n| n.deinit(gpa);
|
||||
note.* = switch (ref) {
|
||||
.import => |import| try Module.ErrorMsg.init(
|
||||
.import => |import| try Zcu.ErrorMsg.init(
|
||||
gpa,
|
||||
.{
|
||||
.base_node_inst = try ip.trackZir(gpa, import.file, .main_struct_inst),
|
||||
@ -2657,7 +2655,7 @@ fn reportMultiModuleErrors(zcu: *Zcu) !void {
|
||||
"imported from module {s}",
|
||||
.{zcu.fileByIndex(import.file).mod.fully_qualified_name},
|
||||
),
|
||||
.root => |pkg| try Module.ErrorMsg.init(
|
||||
.root => |pkg| try Zcu.ErrorMsg.init(
|
||||
gpa,
|
||||
.{
|
||||
.base_node_inst = try ip.trackZir(gpa, file_index, .main_struct_inst),
|
||||
@ -2671,7 +2669,7 @@ fn reportMultiModuleErrors(zcu: *Zcu) !void {
|
||||
errdefer for (notes[0..num_notes]) |*n| n.deinit(gpa);
|
||||
|
||||
if (omitted > 0) {
|
||||
notes[num_notes] = try Module.ErrorMsg.init(
|
||||
notes[num_notes] = try Zcu.ErrorMsg.init(
|
||||
gpa,
|
||||
.{
|
||||
.base_node_inst = try ip.trackZir(gpa, file_index, .main_struct_inst),
|
||||
@ -2683,7 +2681,7 @@ fn reportMultiModuleErrors(zcu: *Zcu) !void {
|
||||
}
|
||||
errdefer if (omitted > 0) notes[num_notes].deinit(gpa);
|
||||
|
||||
const err = try Module.ErrorMsg.create(
|
||||
const err = try Zcu.ErrorMsg.create(
|
||||
gpa,
|
||||
.{
|
||||
.base_node_inst = try ip.trackZir(gpa, file_index, .main_struct_inst),
|
||||
@ -2706,7 +2704,7 @@ fn reportMultiModuleErrors(zcu: *Zcu) !void {
|
||||
|
||||
// There isn't really any meaningful place to put this note, so just attach it to the
|
||||
// last failed file
|
||||
var note = try Module.ErrorMsg.init(
|
||||
var note = try Zcu.ErrorMsg.init(
|
||||
gpa,
|
||||
err.src_loc,
|
||||
"{} more errors omitted",
|
||||
@ -3095,10 +3093,10 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {
|
||||
const values = zcu.compile_log_sources.values();
|
||||
// First one will be the error; subsequent ones will be notes.
|
||||
const src_loc = values[0].src();
|
||||
const err_msg: Module.ErrorMsg = .{
|
||||
const err_msg: Zcu.ErrorMsg = .{
|
||||
.src_loc = src_loc,
|
||||
.msg = "found compile log statement",
|
||||
.notes = try gpa.alloc(Module.ErrorMsg, zcu.compile_log_sources.count() - 1),
|
||||
.notes = try gpa.alloc(Zcu.ErrorMsg, zcu.compile_log_sources.count() - 1),
|
||||
};
|
||||
defer gpa.free(err_msg.notes);
|
||||
|
||||
@ -3166,9 +3164,9 @@ pub const ErrorNoteHashContext = struct {
|
||||
};
|
||||
|
||||
pub fn addModuleErrorMsg(
|
||||
mod: *Module,
|
||||
mod: *Zcu,
|
||||
eb: *ErrorBundle.Wip,
|
||||
module_err_msg: Module.ErrorMsg,
|
||||
module_err_msg: Zcu.ErrorMsg,
|
||||
all_references: *const std.AutoHashMapUnmanaged(InternPool.AnalUnit, Zcu.ResolvedReference),
|
||||
) !void {
|
||||
const gpa = eb.gpa;
|
||||
@ -3299,7 +3297,7 @@ pub fn addModuleErrorMsg(
|
||||
}
|
||||
}
|
||||
|
||||
pub fn addZirErrorMessages(eb: *ErrorBundle.Wip, file: *Module.File) !void {
|
||||
pub fn addZirErrorMessages(eb: *ErrorBundle.Wip, file: *Zcu.File) !void {
|
||||
assert(file.zir_loaded);
|
||||
assert(file.tree_loaded);
|
||||
assert(file.source_loaded);
|
||||
@ -3378,7 +3376,7 @@ pub fn performAllTheWork(
|
||||
const path_digest = zcu.filePathDigest(file_index);
|
||||
const root_decl = zcu.fileRootDecl(file_index);
|
||||
const file = zcu.fileByIndex(file_index);
|
||||
comp.thread_pool.spawnWg(&comp.astgen_wait_group, workerAstGenFile, .{
|
||||
comp.thread_pool.spawnWgId(&comp.astgen_wait_group, workerAstGenFile, .{
|
||||
comp, file, file_index, path_digest, root_decl, zir_prog_node, &comp.astgen_wait_group, .root,
|
||||
});
|
||||
}
|
||||
@ -3587,22 +3585,22 @@ fn processOneJob(tid: usize, comp: *Compilation, job: Job, prog_node: std.Progre
|
||||
defer named_frame.end();
|
||||
|
||||
const gpa = comp.gpa;
|
||||
const zcu = comp.module.?;
|
||||
const decl = zcu.declPtr(decl_index);
|
||||
const pt: Zcu.PerThread = .{ .zcu = comp.module.?, .tid = @enumFromInt(tid) };
|
||||
const decl = pt.zcu.declPtr(decl_index);
|
||||
const lf = comp.bin_file.?;
|
||||
lf.updateDeclLineNumber(zcu, decl_index) catch |err| {
|
||||
try zcu.failed_analysis.ensureUnusedCapacity(gpa, 1);
|
||||
zcu.failed_analysis.putAssumeCapacityNoClobber(
|
||||
lf.updateDeclLineNumber(pt, decl_index) catch |err| {
|
||||
try pt.zcu.failed_analysis.ensureUnusedCapacity(gpa, 1);
|
||||
pt.zcu.failed_analysis.putAssumeCapacityNoClobber(
|
||||
InternPool.AnalUnit.wrap(.{ .decl = decl_index }),
|
||||
try Zcu.ErrorMsg.create(
|
||||
gpa,
|
||||
decl.navSrcLoc(zcu),
|
||||
decl.navSrcLoc(pt.zcu),
|
||||
"unable to update line number: {s}",
|
||||
.{@errorName(err)},
|
||||
),
|
||||
);
|
||||
decl.analysis = .codegen_failure;
|
||||
try zcu.retryable_failures.append(gpa, InternPool.AnalUnit.wrap(.{ .decl = decl_index }));
|
||||
try pt.zcu.retryable_failures.append(gpa, InternPool.AnalUnit.wrap(.{ .decl = decl_index }));
|
||||
};
|
||||
},
|
||||
.analyze_mod => |mod| {
|
||||
@ -4049,6 +4047,7 @@ const AstGenSrc = union(enum) {
|
||||
};
|
||||
|
||||
fn workerAstGenFile(
|
||||
tid: usize,
|
||||
comp: *Compilation,
|
||||
file: *Zcu.File,
|
||||
file_index: Zcu.File.Index,
|
||||
@ -4061,8 +4060,8 @@ fn workerAstGenFile(
|
||||
const child_prog_node = prog_node.start(file.sub_file_path, 0);
|
||||
defer child_prog_node.end();
|
||||
|
||||
const zcu = comp.module.?;
|
||||
zcu.astGenFile(file, file_index, path_digest, root_decl) catch |err| switch (err) {
|
||||
const pt: Zcu.PerThread = .{ .zcu = comp.module.?, .tid = @enumFromInt(tid) };
|
||||
pt.astGenFile(file, file_index, path_digest, root_decl) catch |err| switch (err) {
|
||||
error.AnalysisFail => return,
|
||||
else => {
|
||||
file.status = .retryable_failure;
|
||||
@ -4097,15 +4096,15 @@ fn workerAstGenFile(
|
||||
comp.mutex.lock();
|
||||
defer comp.mutex.unlock();
|
||||
|
||||
const res = zcu.importFile(file, import_path) catch continue;
|
||||
const res = pt.zcu.importFile(file, import_path) catch continue;
|
||||
if (!res.is_pkg) {
|
||||
res.file.addReference(zcu.*, .{ .import = .{
|
||||
res.file.addReference(pt.zcu.*, .{ .import = .{
|
||||
.file = file_index,
|
||||
.token = item.data.token,
|
||||
} }) catch continue;
|
||||
}
|
||||
const imported_path_digest = zcu.filePathDigest(res.file_index);
|
||||
const imported_root_decl = zcu.fileRootDecl(res.file_index);
|
||||
const imported_path_digest = pt.zcu.filePathDigest(res.file_index);
|
||||
const imported_root_decl = pt.zcu.fileRootDecl(res.file_index);
|
||||
break :blk .{ res, imported_path_digest, imported_root_decl };
|
||||
};
|
||||
if (import_result.is_new) {
|
||||
@ -4116,7 +4115,7 @@ fn workerAstGenFile(
|
||||
.importing_file = file_index,
|
||||
.import_tok = item.data.token,
|
||||
} };
|
||||
comp.thread_pool.spawnWg(wg, workerAstGenFile, .{
|
||||
comp.thread_pool.spawnWgId(wg, workerAstGenFile, .{
|
||||
comp, import_result.file, import_result.file_index, imported_path_digest, imported_root_decl, prog_node, wg, sub_src,
|
||||
});
|
||||
}
|
||||
@ -4127,7 +4126,7 @@ fn workerAstGenFile(
|
||||
fn workerUpdateBuiltinZigFile(
|
||||
comp: *Compilation,
|
||||
mod: *Package.Module,
|
||||
file: *Module.File,
|
||||
file: *Zcu.File,
|
||||
) void {
|
||||
Builtin.populateFile(comp, mod, file) catch |err| {
|
||||
comp.mutex.lock();
|
||||
@ -4139,7 +4138,7 @@ fn workerUpdateBuiltinZigFile(
|
||||
};
|
||||
}
|
||||
|
||||
fn workerCheckEmbedFile(comp: *Compilation, embed_file: *Module.EmbedFile) void {
|
||||
fn workerCheckEmbedFile(comp: *Compilation, embed_file: *Zcu.EmbedFile) void {
|
||||
comp.detectEmbedFileUpdate(embed_file) catch |err| {
|
||||
comp.reportRetryableEmbedFileError(embed_file, err) catch |oom| switch (oom) {
|
||||
// Swallowing this error is OK because it's implied to be OOM when
|
||||
@ -4150,7 +4149,7 @@ fn workerCheckEmbedFile(comp: *Compilation, embed_file: *Module.EmbedFile) void
|
||||
};
|
||||
}
|
||||
|
||||
fn detectEmbedFileUpdate(comp: *Compilation, embed_file: *Module.EmbedFile) !void {
|
||||
fn detectEmbedFileUpdate(comp: *Compilation, embed_file: *Zcu.EmbedFile) !void {
|
||||
const mod = comp.module.?;
|
||||
const ip = &mod.intern_pool;
|
||||
var file = try embed_file.owner.root.openFile(embed_file.sub_file_path.toSlice(ip), .{});
|
||||
@ -4477,7 +4476,7 @@ fn reportRetryableAstGenError(
|
||||
const file = zcu.fileByIndex(file_index);
|
||||
file.status = .retryable_failure;
|
||||
|
||||
const src_loc: Module.LazySrcLoc = switch (src) {
|
||||
const src_loc: Zcu.LazySrcLoc = switch (src) {
|
||||
.root => .{
|
||||
.base_node_inst = try zcu.intern_pool.trackZir(gpa, file_index, .main_struct_inst),
|
||||
.offset = .entire_file,
|
||||
@ -4488,7 +4487,7 @@ fn reportRetryableAstGenError(
|
||||
},
|
||||
};
|
||||
|
||||
const err_msg = try Module.ErrorMsg.create(gpa, src_loc, "unable to load '{}{s}': {s}", .{
|
||||
const err_msg = try Zcu.ErrorMsg.create(gpa, src_loc, "unable to load '{}{s}': {s}", .{
|
||||
file.mod.root, file.sub_file_path, @errorName(err),
|
||||
});
|
||||
errdefer err_msg.destroy(gpa);
|
||||
@ -4502,14 +4501,14 @@ fn reportRetryableAstGenError(
|
||||
|
||||
fn reportRetryableEmbedFileError(
|
||||
comp: *Compilation,
|
||||
embed_file: *Module.EmbedFile,
|
||||
embed_file: *Zcu.EmbedFile,
|
||||
err: anyerror,
|
||||
) error{OutOfMemory}!void {
|
||||
const mod = comp.module.?;
|
||||
const gpa = mod.gpa;
|
||||
const src_loc = embed_file.src_loc;
|
||||
const ip = &mod.intern_pool;
|
||||
const err_msg = try Module.ErrorMsg.create(gpa, src_loc, "unable to load '{}{s}': {s}", .{
|
||||
const err_msg = try Zcu.ErrorMsg.create(gpa, src_loc, "unable to load '{}{s}': {s}", .{
|
||||
embed_file.owner.root,
|
||||
embed_file.sub_file_path.toSlice(ip),
|
||||
@errorName(err),
|
||||
|
@ -4539,7 +4539,7 @@ pub fn init(ip: *InternPool, gpa: Allocator) !void {
|
||||
assert(ip.items.len == 0);
|
||||
|
||||
// Reserve string index 0 for an empty string.
|
||||
assert((try ip.getOrPutString(gpa, "", .no_embedded_nulls)) == .empty);
|
||||
assert((try ip.getOrPutString(gpa, .main, "", .no_embedded_nulls)) == .empty);
|
||||
|
||||
// So that we can use `catch unreachable` below.
|
||||
try ip.items.ensureUnusedCapacity(gpa, static_keys.len);
|
||||
@ -5986,6 +5986,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
|
||||
);
|
||||
const string = try ip.getOrPutTrailingString(
|
||||
gpa,
|
||||
tid,
|
||||
@intCast(len_including_sentinel),
|
||||
.maybe_embedded_nulls,
|
||||
);
|
||||
@ -6865,6 +6866,7 @@ pub fn getFuncInstance(
|
||||
return finishFuncInstance(
|
||||
ip,
|
||||
gpa,
|
||||
tid,
|
||||
generic_owner,
|
||||
func_index,
|
||||
func_extra_index,
|
||||
@ -6879,7 +6881,7 @@ pub fn getFuncInstance(
|
||||
pub fn getFuncInstanceIes(
|
||||
ip: *InternPool,
|
||||
gpa: Allocator,
|
||||
_: Zcu.PerThread.Id,
|
||||
tid: Zcu.PerThread.Id,
|
||||
arg: GetFuncInstanceKey,
|
||||
) Allocator.Error!Index {
|
||||
// Validate input parameters.
|
||||
@ -6994,6 +6996,7 @@ pub fn getFuncInstanceIes(
|
||||
return finishFuncInstance(
|
||||
ip,
|
||||
gpa,
|
||||
tid,
|
||||
generic_owner,
|
||||
func_index,
|
||||
func_extra_index,
|
||||
@ -7005,6 +7008,7 @@ pub fn getFuncInstanceIes(
|
||||
fn finishFuncInstance(
|
||||
ip: *InternPool,
|
||||
gpa: Allocator,
|
||||
tid: Zcu.PerThread.Id,
|
||||
generic_owner: Index,
|
||||
func_index: Index,
|
||||
func_extra_index: u32,
|
||||
@ -7036,7 +7040,7 @@ fn finishFuncInstance(
|
||||
|
||||
// TODO: improve this name
|
||||
const decl = ip.declPtr(decl_index);
|
||||
decl.name = try ip.getOrPutStringFmt(gpa, "{}__anon_{d}", .{
|
||||
decl.name = try ip.getOrPutStringFmt(gpa, tid, "{}__anon_{d}", .{
|
||||
fn_owner_decl.name.fmt(ip), @intFromEnum(decl_index),
|
||||
}, .no_embedded_nulls);
|
||||
|
||||
@ -8782,18 +8786,20 @@ const EmbeddedNulls = enum {
|
||||
pub fn getOrPutString(
|
||||
ip: *InternPool,
|
||||
gpa: Allocator,
|
||||
tid: Zcu.PerThread.Id,
|
||||
slice: []const u8,
|
||||
comptime embedded_nulls: EmbeddedNulls,
|
||||
) Allocator.Error!embedded_nulls.StringType() {
|
||||
try ip.string_bytes.ensureUnusedCapacity(gpa, slice.len + 1);
|
||||
ip.string_bytes.appendSliceAssumeCapacity(slice);
|
||||
ip.string_bytes.appendAssumeCapacity(0);
|
||||
return ip.getOrPutTrailingString(gpa, slice.len + 1, embedded_nulls);
|
||||
return ip.getOrPutTrailingString(gpa, tid, slice.len + 1, embedded_nulls);
|
||||
}
|
||||
|
||||
pub fn getOrPutStringFmt(
|
||||
ip: *InternPool,
|
||||
gpa: Allocator,
|
||||
tid: Zcu.PerThread.Id,
|
||||
comptime format: []const u8,
|
||||
args: anytype,
|
||||
comptime embedded_nulls: EmbeddedNulls,
|
||||
@ -8803,16 +8809,17 @@ pub fn getOrPutStringFmt(
|
||||
try ip.string_bytes.ensureUnusedCapacity(gpa, len);
|
||||
ip.string_bytes.writer(undefined).print(format, args) catch unreachable;
|
||||
ip.string_bytes.appendAssumeCapacity(0);
|
||||
return ip.getOrPutTrailingString(gpa, len, embedded_nulls);
|
||||
return ip.getOrPutTrailingString(gpa, tid, len, embedded_nulls);
|
||||
}
|
||||
|
||||
pub fn getOrPutStringOpt(
|
||||
ip: *InternPool,
|
||||
gpa: Allocator,
|
||||
tid: Zcu.PerThread.Id,
|
||||
slice: ?[]const u8,
|
||||
comptime embedded_nulls: EmbeddedNulls,
|
||||
) Allocator.Error!embedded_nulls.OptionalStringType() {
|
||||
const string = try getOrPutString(ip, gpa, slice orelse return .none, embedded_nulls);
|
||||
const string = try getOrPutString(ip, gpa, tid, slice orelse return .none, embedded_nulls);
|
||||
return string.toOptional();
|
||||
}
|
||||
|
||||
@ -8820,9 +8827,11 @@ pub fn getOrPutStringOpt(
|
||||
pub fn getOrPutTrailingString(
|
||||
ip: *InternPool,
|
||||
gpa: Allocator,
|
||||
tid: Zcu.PerThread.Id,
|
||||
len: usize,
|
||||
comptime embedded_nulls: EmbeddedNulls,
|
||||
) Allocator.Error!embedded_nulls.StringType() {
|
||||
_ = tid;
|
||||
const string_bytes = &ip.string_bytes;
|
||||
const str_index: u32 = @intCast(string_bytes.items.len - len);
|
||||
if (len > 0 and string_bytes.getLast() == 0) {
|
||||
|
262
src/Sema.zig
262
src/Sema.zig
@ -2093,12 +2093,12 @@ pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize)
|
||||
const st_ptr = try err_trace_block.addTy(.alloc, try pt.singleMutPtrType(stack_trace_ty));
|
||||
|
||||
// st.instruction_addresses = &addrs;
|
||||
const instruction_addresses_field_name = try ip.getOrPutString(gpa, "instruction_addresses", .no_embedded_nulls);
|
||||
const instruction_addresses_field_name = try ip.getOrPutString(gpa, pt.tid, "instruction_addresses", .no_embedded_nulls);
|
||||
const addr_field_ptr = try sema.fieldPtr(&err_trace_block, src, st_ptr, instruction_addresses_field_name, src, true);
|
||||
try sema.storePtr2(&err_trace_block, src, addr_field_ptr, src, addrs_ptr, src, .store);
|
||||
|
||||
// st.index = 0;
|
||||
const index_field_name = try ip.getOrPutString(gpa, "index", .no_embedded_nulls);
|
||||
const index_field_name = try ip.getOrPutString(gpa, pt.tid, "index", .no_embedded_nulls);
|
||||
const index_field_ptr = try sema.fieldPtr(&err_trace_block, src, st_ptr, index_field_name, src, true);
|
||||
try sema.storePtr2(&err_trace_block, src, index_field_ptr, src, .zero_usize, src, .store);
|
||||
|
||||
@ -2691,6 +2691,7 @@ fn getCaptures(sema: *Sema, block: *Block, type_src: LazySrcLoc, extra_index: us
|
||||
.decl_val => |str| capture: {
|
||||
const decl_name = try ip.getOrPutString(
|
||||
sema.gpa,
|
||||
pt.tid,
|
||||
sema.code.nullTerminatedString(str),
|
||||
.no_embedded_nulls,
|
||||
);
|
||||
@ -2700,6 +2701,7 @@ fn getCaptures(sema: *Sema, block: *Block, type_src: LazySrcLoc, extra_index: us
|
||||
.decl_ref => |str| capture: {
|
||||
const decl_name = try ip.getOrPutString(
|
||||
sema.gpa,
|
||||
pt.tid,
|
||||
sema.code.nullTerminatedString(str),
|
||||
.no_embedded_nulls,
|
||||
);
|
||||
@ -2847,7 +2849,7 @@ fn zirStructDecl(
|
||||
|
||||
if (new_namespace_index.unwrap()) |ns| {
|
||||
const decls = sema.code.bodySlice(extra_index, decls_len);
|
||||
try mod.scanNamespace(ns, decls, mod.declPtr(new_decl_index));
|
||||
try pt.scanNamespace(ns, decls, mod.declPtr(new_decl_index));
|
||||
}
|
||||
|
||||
try pt.finalizeAnonDecl(new_decl_index);
|
||||
@ -2919,7 +2921,7 @@ fn createAnonymousDeclTypeNamed(
|
||||
};
|
||||
|
||||
try writer.writeByte(')');
|
||||
const name = try ip.getOrPutString(gpa, buf.items, .no_embedded_nulls);
|
||||
const name = try ip.getOrPutString(gpa, pt.tid, buf.items, .no_embedded_nulls);
|
||||
try zcu.initNewAnonDecl(new_decl_index, val, name);
|
||||
return new_decl_index;
|
||||
},
|
||||
@ -2931,7 +2933,7 @@ fn createAnonymousDeclTypeNamed(
|
||||
.dbg_var_ptr, .dbg_var_val => {
|
||||
if (zir_data[i].str_op.operand != ref) continue;
|
||||
|
||||
const name = try ip.getOrPutStringFmt(gpa, "{}.{s}", .{
|
||||
const name = try ip.getOrPutStringFmt(gpa, pt.tid, "{}.{s}", .{
|
||||
block.type_name_ctx.fmt(ip), zir_data[i].str_op.getStr(sema.code),
|
||||
}, .no_embedded_nulls);
|
||||
try zcu.initNewAnonDecl(new_decl_index, val, name);
|
||||
@ -2952,7 +2954,7 @@ fn createAnonymousDeclTypeNamed(
|
||||
// This name is also used as the key in the parent namespace so it cannot be
|
||||
// renamed.
|
||||
|
||||
const name = ip.getOrPutStringFmt(gpa, "{}__{s}_{d}", .{
|
||||
const name = ip.getOrPutStringFmt(gpa, pt.tid, "{}__{s}_{d}", .{
|
||||
block.type_name_ctx.fmt(ip), anon_prefix, @intFromEnum(new_decl_index),
|
||||
}, .no_embedded_nulls) catch unreachable;
|
||||
try zcu.initNewAnonDecl(new_decl_index, val, name);
|
||||
@ -3084,7 +3086,7 @@ fn zirEnumDecl(
|
||||
errdefer if (!done) if (new_namespace_index.unwrap()) |ns| mod.destroyNamespace(ns);
|
||||
|
||||
if (new_namespace_index.unwrap()) |ns| {
|
||||
try mod.scanNamespace(ns, decls, new_decl);
|
||||
try pt.scanNamespace(ns, decls, new_decl);
|
||||
}
|
||||
|
||||
// We've finished the initial construction of this type, and are about to perform analysis.
|
||||
@ -3169,7 +3171,7 @@ fn zirEnumDecl(
|
||||
const field_name_zir = sema.code.nullTerminatedString(field_name_index);
|
||||
extra_index += 2; // field name, doc comment
|
||||
|
||||
const field_name = try mod.intern_pool.getOrPutString(gpa, field_name_zir, .no_embedded_nulls);
|
||||
const field_name = try mod.intern_pool.getOrPutString(gpa, pt.tid, field_name_zir, .no_embedded_nulls);
|
||||
|
||||
const value_src: LazySrcLoc = .{
|
||||
.base_node_inst = tracked_inst,
|
||||
@ -3352,7 +3354,7 @@ fn zirUnionDecl(
|
||||
|
||||
if (new_namespace_index.unwrap()) |ns| {
|
||||
const decls = sema.code.bodySlice(extra_index, decls_len);
|
||||
try mod.scanNamespace(ns, decls, mod.declPtr(new_decl_index));
|
||||
try pt.scanNamespace(ns, decls, mod.declPtr(new_decl_index));
|
||||
}
|
||||
|
||||
try pt.finalizeAnonDecl(new_decl_index);
|
||||
@ -3441,7 +3443,7 @@ fn zirOpaqueDecl(
|
||||
|
||||
if (new_namespace_index.unwrap()) |ns| {
|
||||
const decls = sema.code.bodySlice(extra_index, decls_len);
|
||||
try mod.scanNamespace(ns, decls, mod.declPtr(new_decl_index));
|
||||
try pt.scanNamespace(ns, decls, mod.declPtr(new_decl_index));
|
||||
}
|
||||
|
||||
try pt.finalizeAnonDecl(new_decl_index);
|
||||
@ -3470,7 +3472,7 @@ fn zirErrorSetDecl(
|
||||
while (extra_index < extra_index_end) : (extra_index += 2) { // +2 to skip over doc_string
|
||||
const name_index: Zir.NullTerminatedString = @enumFromInt(sema.code.extra[extra_index]);
|
||||
const name = sema.code.nullTerminatedString(name_index);
|
||||
const name_ip = try mod.intern_pool.getOrPutString(gpa, name, .no_embedded_nulls);
|
||||
const name_ip = try mod.intern_pool.getOrPutString(gpa, pt.tid, name, .no_embedded_nulls);
|
||||
_ = try mod.getErrorValue(name_ip);
|
||||
const result = names.getOrPutAssumeCapacity(name_ip);
|
||||
assert(!result.found_existing); // verified in AstGen
|
||||
@ -3634,7 +3636,7 @@ fn indexablePtrLen(
|
||||
const is_pointer_to = object_ty.isSinglePointer(mod);
|
||||
const indexable_ty = if (is_pointer_to) object_ty.childType(mod) else object_ty;
|
||||
try checkIndexable(sema, block, src, indexable_ty);
|
||||
const field_name = try mod.intern_pool.getOrPutString(sema.gpa, "len", .no_embedded_nulls);
|
||||
const field_name = try mod.intern_pool.getOrPutString(sema.gpa, pt.tid, "len", .no_embedded_nulls);
|
||||
return sema.fieldVal(block, src, object, field_name, src);
|
||||
}
|
||||
|
||||
@ -3649,7 +3651,7 @@ fn indexablePtrLenOrNone(
|
||||
const operand_ty = sema.typeOf(operand);
|
||||
try checkMemOperand(sema, block, src, operand_ty);
|
||||
if (operand_ty.ptrSize(mod) == .Many) return .none;
|
||||
const field_name = try mod.intern_pool.getOrPutString(sema.gpa, "len", .no_embedded_nulls);
|
||||
const field_name = try mod.intern_pool.getOrPutString(sema.gpa, pt.tid, "len", .no_embedded_nulls);
|
||||
return sema.fieldVal(block, src, operand, field_name, src);
|
||||
}
|
||||
|
||||
@ -4405,7 +4407,7 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
|
||||
}
|
||||
if (!object_ty.indexableHasLen(mod)) continue;
|
||||
|
||||
break :l try sema.fieldVal(block, arg_src, object, try ip.getOrPutString(gpa, "len", .no_embedded_nulls), arg_src);
|
||||
break :l try sema.fieldVal(block, arg_src, object, try ip.getOrPutString(gpa, pt.tid, "len", .no_embedded_nulls), arg_src);
|
||||
};
|
||||
const arg_len = try sema.coerce(block, Type.usize, arg_len_uncoerced, arg_src);
|
||||
if (len == .none) {
|
||||
@ -4797,6 +4799,7 @@ fn validateUnionInit(
|
||||
const field_ptr_extra = sema.code.extraData(Zir.Inst.Field, field_ptr_data.payload_index).data;
|
||||
const field_name = try mod.intern_pool.getOrPutString(
|
||||
gpa,
|
||||
pt.tid,
|
||||
sema.code.nullTerminatedString(field_ptr_extra.field_name_start),
|
||||
.no_embedded_nulls,
|
||||
);
|
||||
@ -4942,6 +4945,7 @@ fn validateStructInit(
|
||||
struct_ptr_zir_ref = field_ptr_extra.lhs;
|
||||
const field_name = try ip.getOrPutString(
|
||||
gpa,
|
||||
pt.tid,
|
||||
sema.code.nullTerminatedString(field_ptr_extra.field_name_start),
|
||||
.no_embedded_nulls,
|
||||
);
|
||||
@ -5518,10 +5522,11 @@ fn failWithBadStructFieldAccess(
|
||||
field_src: LazySrcLoc,
|
||||
field_name: InternPool.NullTerminatedString,
|
||||
) CompileError {
|
||||
const zcu = sema.pt.zcu;
|
||||
const pt = sema.pt;
|
||||
const zcu = pt.zcu;
|
||||
const ip = &zcu.intern_pool;
|
||||
const decl = zcu.declPtr(struct_type.decl.unwrap().?);
|
||||
const fqn = try decl.fullyQualifiedName(zcu);
|
||||
const fqn = try decl.fullyQualifiedName(pt);
|
||||
|
||||
const msg = msg: {
|
||||
const msg = try sema.errMsg(
|
||||
@ -5544,12 +5549,13 @@ fn failWithBadUnionFieldAccess(
|
||||
field_src: LazySrcLoc,
|
||||
field_name: InternPool.NullTerminatedString,
|
||||
) CompileError {
|
||||
const zcu = sema.pt.zcu;
|
||||
const pt = sema.pt;
|
||||
const zcu = pt.zcu;
|
||||
const ip = &zcu.intern_pool;
|
||||
const gpa = sema.gpa;
|
||||
|
||||
const decl = zcu.declPtr(union_obj.decl);
|
||||
const fqn = try decl.fullyQualifiedName(zcu);
|
||||
const fqn = try decl.fullyQualifiedName(pt);
|
||||
|
||||
const msg = msg: {
|
||||
const msg = try sema.errMsg(
|
||||
@ -5715,7 +5721,7 @@ fn zirStoreNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!v
|
||||
fn zirStr(sema: *Sema, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
|
||||
const bytes = sema.code.instructions.items(.data)[@intFromEnum(inst)].str.get(sema.code);
|
||||
return sema.addStrLit(
|
||||
try sema.pt.zcu.intern_pool.getOrPutString(sema.gpa, bytes, .maybe_embedded_nulls),
|
||||
try sema.pt.zcu.intern_pool.getOrPutString(sema.gpa, sema.pt.tid, bytes, .maybe_embedded_nulls),
|
||||
bytes.len,
|
||||
);
|
||||
}
|
||||
@ -6057,7 +6063,7 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr
|
||||
|
||||
const path_digest = zcu.filePathDigest(result.file_index);
|
||||
const root_decl = zcu.fileRootDecl(result.file_index);
|
||||
zcu.astGenFile(result.file, result.file_index, path_digest, root_decl) catch |err|
|
||||
pt.astGenFile(result.file, result.file_index, path_digest, root_decl) catch |err|
|
||||
return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)});
|
||||
|
||||
try pt.ensureFileAnalyzed(result.file_index);
|
||||
@ -6418,6 +6424,7 @@ fn zirExport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
|
||||
const options_src = block.builtinCallArgSrc(inst_data.src_node, 1);
|
||||
const decl_name = try mod.intern_pool.getOrPutString(
|
||||
mod.gpa,
|
||||
pt.tid,
|
||||
sema.code.nullTerminatedString(extra.decl_name),
|
||||
.no_embedded_nulls,
|
||||
);
|
||||
@ -6737,6 +6744,7 @@ fn zirDeclRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
|
||||
const src = block.tokenOffset(inst_data.src_tok);
|
||||
const decl_name = try mod.intern_pool.getOrPutString(
|
||||
sema.gpa,
|
||||
pt.tid,
|
||||
inst_data.get(sema.code),
|
||||
.no_embedded_nulls,
|
||||
);
|
||||
@ -6751,6 +6759,7 @@ fn zirDeclVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
|
||||
const src = block.tokenOffset(inst_data.src_tok);
|
||||
const decl_name = try mod.intern_pool.getOrPutString(
|
||||
sema.gpa,
|
||||
pt.tid,
|
||||
inst_data.get(sema.code),
|
||||
.no_embedded_nulls,
|
||||
);
|
||||
@ -6907,7 +6916,7 @@ pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref
|
||||
|
||||
const stack_trace_ty = try pt.getBuiltinType("StackTrace");
|
||||
try stack_trace_ty.resolveFields(pt);
|
||||
const field_name = try mod.intern_pool.getOrPutString(gpa, "index", .no_embedded_nulls);
|
||||
const field_name = try mod.intern_pool.getOrPutString(gpa, pt.tid, "index", .no_embedded_nulls);
|
||||
const field_index = sema.structFieldIndex(block, stack_trace_ty, field_name, LazySrcLoc.unneeded) catch |err| switch (err) {
|
||||
error.AnalysisFail => @panic("std.builtin.StackTrace is corrupt"),
|
||||
error.GenericPoison, error.ComptimeReturn, error.ComptimeBreak => unreachable,
|
||||
@ -6951,7 +6960,7 @@ fn popErrorReturnTrace(
|
||||
try stack_trace_ty.resolveFields(pt);
|
||||
const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty);
|
||||
const err_return_trace = try block.addTy(.err_return_trace, ptr_stack_trace_ty);
|
||||
const field_name = try mod.intern_pool.getOrPutString(gpa, "index", .no_embedded_nulls);
|
||||
const field_name = try mod.intern_pool.getOrPutString(gpa, pt.tid, "index", .no_embedded_nulls);
|
||||
const field_ptr = try sema.structFieldPtr(block, src, err_return_trace, field_name, src, stack_trace_ty, true);
|
||||
try sema.storePtr2(block, src, field_ptr, src, saved_error_trace_index, src, .store);
|
||||
} else if (is_non_error == null) {
|
||||
@ -6977,7 +6986,7 @@ fn popErrorReturnTrace(
|
||||
try stack_trace_ty.resolveFields(pt);
|
||||
const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty);
|
||||
const err_return_trace = try then_block.addTy(.err_return_trace, ptr_stack_trace_ty);
|
||||
const field_name = try mod.intern_pool.getOrPutString(gpa, "index", .no_embedded_nulls);
|
||||
const field_name = try mod.intern_pool.getOrPutString(gpa, pt.tid, "index", .no_embedded_nulls);
|
||||
const field_ptr = try sema.structFieldPtr(&then_block, src, err_return_trace, field_name, src, stack_trace_ty, true);
|
||||
try sema.storePtr2(&then_block, src, field_ptr, src, saved_error_trace_index, src, .store);
|
||||
_ = try then_block.addBr(cond_block_inst, .void_value);
|
||||
@ -7038,6 +7047,7 @@ fn zirCall(
|
||||
const object_ptr = try sema.resolveInst(extra.data.obj_ptr);
|
||||
const field_name = try mod.intern_pool.getOrPutString(
|
||||
sema.gpa,
|
||||
pt.tid,
|
||||
sema.code.nullTerminatedString(extra.data.field_name_start),
|
||||
.no_embedded_nulls,
|
||||
);
|
||||
@ -7103,7 +7113,7 @@ fn zirCall(
|
||||
if (input_is_error or (pop_error_return_trace and return_ty.isError(mod))) {
|
||||
const stack_trace_ty = try pt.getBuiltinType("StackTrace");
|
||||
try stack_trace_ty.resolveFields(pt);
|
||||
const field_name = try mod.intern_pool.getOrPutString(sema.gpa, "index", .no_embedded_nulls);
|
||||
const field_name = try mod.intern_pool.getOrPutString(sema.gpa, pt.tid, "index", .no_embedded_nulls);
|
||||
const field_index = try sema.structFieldIndex(block, stack_trace_ty, field_name, call_src);
|
||||
|
||||
// Insert a save instruction before the arg resolution + call instructions we just generated
|
||||
@ -8687,6 +8697,7 @@ fn zirErrorValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
|
||||
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok;
|
||||
const name = try pt.zcu.intern_pool.getOrPutString(
|
||||
sema.gpa,
|
||||
pt.tid,
|
||||
inst_data.get(sema.code),
|
||||
.no_embedded_nulls,
|
||||
);
|
||||
@ -8849,7 +8860,7 @@ fn zirEnumLiteral(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
|
||||
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok;
|
||||
const name = inst_data.get(sema.code);
|
||||
return Air.internedToRef((try pt.intern(.{
|
||||
.enum_literal = try mod.intern_pool.getOrPutString(sema.gpa, name, .no_embedded_nulls),
|
||||
.enum_literal = try mod.intern_pool.getOrPutString(sema.gpa, pt.tid, name, .no_embedded_nulls),
|
||||
})));
|
||||
}
|
||||
|
||||
@ -9820,7 +9831,7 @@ fn funcCommon(
|
||||
const func_index = try ip.getExternFunc(gpa, pt.tid, .{
|
||||
.ty = func_ty,
|
||||
.decl = sema.owner_decl_index,
|
||||
.lib_name = try mod.intern_pool.getOrPutStringOpt(gpa, opt_lib_name, .no_embedded_nulls),
|
||||
.lib_name = try mod.intern_pool.getOrPutStringOpt(gpa, pt.tid, opt_lib_name, .no_embedded_nulls),
|
||||
});
|
||||
return finishFunc(
|
||||
sema,
|
||||
@ -10281,6 +10292,7 @@ fn zirFieldVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
const extra = sema.code.extraData(Zir.Inst.Field, inst_data.payload_index).data;
|
||||
const field_name = try mod.intern_pool.getOrPutString(
|
||||
sema.gpa,
|
||||
pt.tid,
|
||||
sema.code.nullTerminatedString(extra.field_name_start),
|
||||
.no_embedded_nulls,
|
||||
);
|
||||
@ -10300,6 +10312,7 @@ fn zirFieldPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
const extra = sema.code.extraData(Zir.Inst.Field, inst_data.payload_index).data;
|
||||
const field_name = try mod.intern_pool.getOrPutString(
|
||||
sema.gpa,
|
||||
pt.tid,
|
||||
sema.code.nullTerminatedString(extra.field_name_start),
|
||||
.no_embedded_nulls,
|
||||
);
|
||||
@ -10319,6 +10332,7 @@ fn zirStructInitFieldPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compi
|
||||
const extra = sema.code.extraData(Zir.Inst.Field, inst_data.payload_index).data;
|
||||
const field_name = try mod.intern_pool.getOrPutString(
|
||||
sema.gpa,
|
||||
pt.tid,
|
||||
sema.code.nullTerminatedString(extra.field_name_start),
|
||||
.no_embedded_nulls,
|
||||
);
|
||||
@ -13983,6 +13997,7 @@ fn zirRetErrValueCode(sema: *Sema, inst: Zir.Inst.Index) CompileError!Air.Inst.R
|
||||
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok;
|
||||
const name = try mod.intern_pool.getOrPutString(
|
||||
sema.gpa,
|
||||
pt.tid,
|
||||
inst_data.get(sema.code),
|
||||
.no_embedded_nulls,
|
||||
);
|
||||
@ -17716,7 +17731,7 @@ fn zirBuiltinSrc(
|
||||
.val = try pt.intern(.{ .aggregate = .{
|
||||
.ty = array_ty,
|
||||
.storage = .{
|
||||
.bytes = try ip.getOrPutString(gpa, file_name, .maybe_embedded_nulls),
|
||||
.bytes = try ip.getOrPutString(gpa, pt.tid, file_name, .maybe_embedded_nulls),
|
||||
},
|
||||
} }),
|
||||
} },
|
||||
@ -17778,7 +17793,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
block,
|
||||
src,
|
||||
type_info_ty.getNamespaceIndex(mod),
|
||||
try ip.getOrPutString(gpa, "Fn", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "Fn", .no_embedded_nulls),
|
||||
)).?;
|
||||
try sema.ensureDeclAnalyzed(fn_info_decl_index);
|
||||
const fn_info_decl = mod.declPtr(fn_info_decl_index);
|
||||
@ -17788,7 +17803,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
block,
|
||||
src,
|
||||
fn_info_ty.getNamespaceIndex(mod),
|
||||
try ip.getOrPutString(gpa, "Param", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "Param", .no_embedded_nulls),
|
||||
)).?;
|
||||
try sema.ensureDeclAnalyzed(param_info_decl_index);
|
||||
const param_info_decl = mod.declPtr(param_info_decl_index);
|
||||
@ -17890,7 +17905,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
block,
|
||||
src,
|
||||
type_info_ty.getNamespaceIndex(mod),
|
||||
try ip.getOrPutString(gpa, "Int", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "Int", .no_embedded_nulls),
|
||||
)).?;
|
||||
try sema.ensureDeclAnalyzed(int_info_decl_index);
|
||||
const int_info_decl = mod.declPtr(int_info_decl_index);
|
||||
@ -17918,7 +17933,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
block,
|
||||
src,
|
||||
type_info_ty.getNamespaceIndex(mod),
|
||||
try ip.getOrPutString(gpa, "Float", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "Float", .no_embedded_nulls),
|
||||
)).?;
|
||||
try sema.ensureDeclAnalyzed(float_info_decl_index);
|
||||
const float_info_decl = mod.declPtr(float_info_decl_index);
|
||||
@ -17950,7 +17965,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
block,
|
||||
src,
|
||||
(try pt.getBuiltinType("Type")).getNamespaceIndex(mod),
|
||||
try ip.getOrPutString(gpa, "Pointer", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "Pointer", .no_embedded_nulls),
|
||||
)).?;
|
||||
try sema.ensureDeclAnalyzed(decl_index);
|
||||
const decl = mod.declPtr(decl_index);
|
||||
@ -17961,7 +17976,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
block,
|
||||
src,
|
||||
pointer_ty.getNamespaceIndex(mod),
|
||||
try ip.getOrPutString(gpa, "Size", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "Size", .no_embedded_nulls),
|
||||
)).?;
|
||||
try sema.ensureDeclAnalyzed(decl_index);
|
||||
const decl = mod.declPtr(decl_index);
|
||||
@ -18004,7 +18019,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
block,
|
||||
src,
|
||||
type_info_ty.getNamespaceIndex(mod),
|
||||
try ip.getOrPutString(gpa, "Array", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "Array", .no_embedded_nulls),
|
||||
)).?;
|
||||
try sema.ensureDeclAnalyzed(array_field_ty_decl_index);
|
||||
const array_field_ty_decl = mod.declPtr(array_field_ty_decl_index);
|
||||
@ -18035,7 +18050,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
block,
|
||||
src,
|
||||
type_info_ty.getNamespaceIndex(mod),
|
||||
try ip.getOrPutString(gpa, "Vector", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "Vector", .no_embedded_nulls),
|
||||
)).?;
|
||||
try sema.ensureDeclAnalyzed(vector_field_ty_decl_index);
|
||||
const vector_field_ty_decl = mod.declPtr(vector_field_ty_decl_index);
|
||||
@ -18064,7 +18079,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
block,
|
||||
src,
|
||||
type_info_ty.getNamespaceIndex(mod),
|
||||
try ip.getOrPutString(gpa, "Optional", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "Optional", .no_embedded_nulls),
|
||||
)).?;
|
||||
try sema.ensureDeclAnalyzed(optional_field_ty_decl_index);
|
||||
const optional_field_ty_decl = mod.declPtr(optional_field_ty_decl_index);
|
||||
@ -18091,7 +18106,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
block,
|
||||
src,
|
||||
type_info_ty.getNamespaceIndex(mod),
|
||||
try ip.getOrPutString(gpa, "Error", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "Error", .no_embedded_nulls),
|
||||
)).?;
|
||||
try sema.ensureDeclAnalyzed(set_field_ty_decl_index);
|
||||
const set_field_ty_decl = mod.declPtr(set_field_ty_decl_index);
|
||||
@ -18197,7 +18212,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
block,
|
||||
src,
|
||||
type_info_ty.getNamespaceIndex(mod),
|
||||
try ip.getOrPutString(gpa, "ErrorUnion", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "ErrorUnion", .no_embedded_nulls),
|
||||
)).?;
|
||||
try sema.ensureDeclAnalyzed(error_union_field_ty_decl_index);
|
||||
const error_union_field_ty_decl = mod.declPtr(error_union_field_ty_decl_index);
|
||||
@ -18227,7 +18242,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
block,
|
||||
src,
|
||||
type_info_ty.getNamespaceIndex(mod),
|
||||
try ip.getOrPutString(gpa, "EnumField", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "EnumField", .no_embedded_nulls),
|
||||
)).?;
|
||||
try sema.ensureDeclAnalyzed(enum_field_ty_decl_index);
|
||||
const enum_field_ty_decl = mod.declPtr(enum_field_ty_decl_index);
|
||||
@ -18324,7 +18339,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
block,
|
||||
src,
|
||||
type_info_ty.getNamespaceIndex(mod),
|
||||
try ip.getOrPutString(gpa, "Enum", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "Enum", .no_embedded_nulls),
|
||||
)).?;
|
||||
try sema.ensureDeclAnalyzed(type_enum_ty_decl_index);
|
||||
const type_enum_ty_decl = mod.declPtr(type_enum_ty_decl_index);
|
||||
@ -18356,7 +18371,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
block,
|
||||
src,
|
||||
type_info_ty.getNamespaceIndex(mod),
|
||||
try ip.getOrPutString(gpa, "Union", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "Union", .no_embedded_nulls),
|
||||
)).?;
|
||||
try sema.ensureDeclAnalyzed(type_union_ty_decl_index);
|
||||
const type_union_ty_decl = mod.declPtr(type_union_ty_decl_index);
|
||||
@ -18368,7 +18383,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
block,
|
||||
src,
|
||||
type_info_ty.getNamespaceIndex(mod),
|
||||
try ip.getOrPutString(gpa, "UnionField", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "UnionField", .no_embedded_nulls),
|
||||
)).?;
|
||||
try sema.ensureDeclAnalyzed(union_field_ty_decl_index);
|
||||
const union_field_ty_decl = mod.declPtr(union_field_ty_decl_index);
|
||||
@ -18473,7 +18488,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
block,
|
||||
src,
|
||||
(try pt.getBuiltinType("Type")).getNamespaceIndex(mod),
|
||||
try ip.getOrPutString(gpa, "ContainerLayout", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "ContainerLayout", .no_embedded_nulls),
|
||||
)).?;
|
||||
try sema.ensureDeclAnalyzed(decl_index);
|
||||
const decl = mod.declPtr(decl_index);
|
||||
@ -18506,7 +18521,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
block,
|
||||
src,
|
||||
type_info_ty.getNamespaceIndex(mod),
|
||||
try ip.getOrPutString(gpa, "Struct", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "Struct", .no_embedded_nulls),
|
||||
)).?;
|
||||
try sema.ensureDeclAnalyzed(type_struct_ty_decl_index);
|
||||
const type_struct_ty_decl = mod.declPtr(type_struct_ty_decl_index);
|
||||
@ -18518,7 +18533,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
block,
|
||||
src,
|
||||
type_info_ty.getNamespaceIndex(mod),
|
||||
try ip.getOrPutString(gpa, "StructField", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "StructField", .no_embedded_nulls),
|
||||
)).?;
|
||||
try sema.ensureDeclAnalyzed(struct_field_ty_decl_index);
|
||||
const struct_field_ty_decl = mod.declPtr(struct_field_ty_decl_index);
|
||||
@ -18540,7 +18555,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
const field_name = if (anon_struct_type.names.len != 0)
|
||||
anon_struct_type.names.get(ip)[field_index]
|
||||
else
|
||||
try ip.getOrPutStringFmt(gpa, "{d}", .{field_index}, .no_embedded_nulls);
|
||||
try ip.getOrPutStringFmt(gpa, pt.tid, "{d}", .{field_index}, .no_embedded_nulls);
|
||||
const field_name_len = field_name.length(ip);
|
||||
const new_decl_ty = try pt.arrayType(.{
|
||||
.len = field_name_len,
|
||||
@ -18600,7 +18615,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
const field_name = if (struct_type.fieldName(ip, field_index).unwrap()) |field_name|
|
||||
field_name
|
||||
else
|
||||
try ip.getOrPutStringFmt(gpa, "{d}", .{field_index}, .no_embedded_nulls);
|
||||
try ip.getOrPutStringFmt(gpa, pt.tid, "{d}", .{field_index}, .no_embedded_nulls);
|
||||
const field_name_len = field_name.length(ip);
|
||||
const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);
|
||||
const field_init = struct_type.fieldInit(ip, field_index);
|
||||
@ -18706,7 +18721,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
block,
|
||||
src,
|
||||
(try pt.getBuiltinType("Type")).getNamespaceIndex(mod),
|
||||
try ip.getOrPutString(gpa, "ContainerLayout", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "ContainerLayout", .no_embedded_nulls),
|
||||
)).?;
|
||||
try sema.ensureDeclAnalyzed(decl_index);
|
||||
const decl = mod.declPtr(decl_index);
|
||||
@ -18742,7 +18757,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
block,
|
||||
src,
|
||||
type_info_ty.getNamespaceIndex(mod),
|
||||
try ip.getOrPutString(gpa, "Opaque", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "Opaque", .no_embedded_nulls),
|
||||
)).?;
|
||||
try sema.ensureDeclAnalyzed(type_opaque_ty_decl_index);
|
||||
const type_opaque_ty_decl = mod.declPtr(type_opaque_ty_decl_index);
|
||||
@ -18786,7 +18801,7 @@ fn typeInfoDecls(
|
||||
block,
|
||||
src,
|
||||
type_info_ty.getNamespaceIndex(mod),
|
||||
try mod.intern_pool.getOrPutString(gpa, "Declaration", .no_embedded_nulls),
|
||||
try mod.intern_pool.getOrPutString(gpa, pt.tid, "Declaration", .no_embedded_nulls),
|
||||
)).?;
|
||||
try sema.ensureDeclAnalyzed(declaration_ty_decl_index);
|
||||
const declaration_ty_decl = mod.declPtr(declaration_ty_decl_index);
|
||||
@ -19541,6 +19556,7 @@ fn zirRetErrValue(
|
||||
const src = block.tokenOffset(inst_data.src_tok);
|
||||
const err_name = try mod.intern_pool.getOrPutString(
|
||||
sema.gpa,
|
||||
pt.tid,
|
||||
inst_data.get(sema.code),
|
||||
.no_embedded_nulls,
|
||||
);
|
||||
@ -20251,6 +20267,7 @@ fn zirStructInit(
|
||||
const field_type_extra = sema.code.extraData(Zir.Inst.FieldType, field_type_data.payload_index).data;
|
||||
const field_name = try ip.getOrPutString(
|
||||
gpa,
|
||||
pt.tid,
|
||||
sema.code.nullTerminatedString(field_type_extra.name_start),
|
||||
.no_embedded_nulls,
|
||||
);
|
||||
@ -20292,6 +20309,7 @@ fn zirStructInit(
|
||||
const field_type_extra = sema.code.extraData(Zir.Inst.FieldType, field_type_data.payload_index).data;
|
||||
const field_name = try ip.getOrPutString(
|
||||
gpa,
|
||||
pt.tid,
|
||||
sema.code.nullTerminatedString(field_type_extra.name_start),
|
||||
.no_embedded_nulls,
|
||||
);
|
||||
@ -20581,7 +20599,7 @@ fn structInitAnon(
|
||||
},
|
||||
};
|
||||
|
||||
field_name.* = try mod.intern_pool.getOrPutString(gpa, name, .no_embedded_nulls);
|
||||
field_name.* = try mod.intern_pool.getOrPutString(gpa, pt.tid, name, .no_embedded_nulls);
|
||||
|
||||
const init = try sema.resolveInst(item.data.init);
|
||||
field_ty.* = sema.typeOf(init).toIntern();
|
||||
@ -20958,7 +20976,7 @@ fn zirStructInitFieldType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp
|
||||
};
|
||||
const aggregate_ty = wrapped_aggregate_ty.optEuBaseType(mod);
|
||||
const zir_field_name = sema.code.nullTerminatedString(extra.name_start);
|
||||
const field_name = try ip.getOrPutString(sema.gpa, zir_field_name, .no_embedded_nulls);
|
||||
const field_name = try ip.getOrPutString(sema.gpa, pt.tid, zir_field_name, .no_embedded_nulls);
|
||||
return sema.fieldType(block, aggregate_ty, field_name, field_name_src, ty_src);
|
||||
}
|
||||
|
||||
@ -21344,11 +21362,11 @@ fn zirReify(
|
||||
const struct_type = ip.loadStructType(ip.typeOf(union_val.val));
|
||||
const signedness_val = try Value.fromInterned(union_val.val).fieldValue(
|
||||
pt,
|
||||
struct_type.nameIndex(ip, try ip.getOrPutString(gpa, "signedness", .no_embedded_nulls)).?,
|
||||
struct_type.nameIndex(ip, try ip.getOrPutString(gpa, pt.tid, "signedness", .no_embedded_nulls)).?,
|
||||
);
|
||||
const bits_val = try Value.fromInterned(union_val.val).fieldValue(
|
||||
pt,
|
||||
struct_type.nameIndex(ip, try ip.getOrPutString(gpa, "bits", .no_embedded_nulls)).?,
|
||||
struct_type.nameIndex(ip, try ip.getOrPutString(gpa, pt.tid, "bits", .no_embedded_nulls)).?,
|
||||
);
|
||||
|
||||
const signedness = mod.toEnum(std.builtin.Signedness, signedness_val);
|
||||
@ -21360,11 +21378,11 @@ fn zirReify(
|
||||
const struct_type = ip.loadStructType(ip.typeOf(union_val.val));
|
||||
const len_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
|
||||
ip,
|
||||
try ip.getOrPutString(gpa, "len", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "len", .no_embedded_nulls),
|
||||
).?);
|
||||
const child_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
|
||||
ip,
|
||||
try ip.getOrPutString(gpa, "child", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "child", .no_embedded_nulls),
|
||||
).?);
|
||||
|
||||
const len: u32 = @intCast(try len_val.toUnsignedIntSema(pt));
|
||||
@ -21382,7 +21400,7 @@ fn zirReify(
|
||||
const struct_type = ip.loadStructType(ip.typeOf(union_val.val));
|
||||
const bits_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
|
||||
ip,
|
||||
try ip.getOrPutString(gpa, "bits", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "bits", .no_embedded_nulls),
|
||||
).?);
|
||||
|
||||
const bits: u16 = @intCast(try bits_val.toUnsignedIntSema(pt));
|
||||
@ -21400,35 +21418,35 @@ fn zirReify(
|
||||
const struct_type = ip.loadStructType(ip.typeOf(union_val.val));
|
||||
const size_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
|
||||
ip,
|
||||
try ip.getOrPutString(gpa, "size", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "size", .no_embedded_nulls),
|
||||
).?);
|
||||
const is_const_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
|
||||
ip,
|
||||
try ip.getOrPutString(gpa, "is_const", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "is_const", .no_embedded_nulls),
|
||||
).?);
|
||||
const is_volatile_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
|
||||
ip,
|
||||
try ip.getOrPutString(gpa, "is_volatile", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "is_volatile", .no_embedded_nulls),
|
||||
).?);
|
||||
const alignment_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
|
||||
ip,
|
||||
try ip.getOrPutString(gpa, "alignment", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "alignment", .no_embedded_nulls),
|
||||
).?);
|
||||
const address_space_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
|
||||
ip,
|
||||
try ip.getOrPutString(gpa, "address_space", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "address_space", .no_embedded_nulls),
|
||||
).?);
|
||||
const child_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
|
||||
ip,
|
||||
try ip.getOrPutString(gpa, "child", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "child", .no_embedded_nulls),
|
||||
).?);
|
||||
const is_allowzero_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
|
||||
ip,
|
||||
try ip.getOrPutString(gpa, "is_allowzero", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "is_allowzero", .no_embedded_nulls),
|
||||
).?);
|
||||
const sentinel_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
|
||||
ip,
|
||||
try ip.getOrPutString(gpa, "sentinel", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "sentinel", .no_embedded_nulls),
|
||||
).?);
|
||||
|
||||
if (!try sema.intFitsInType(alignment_val, Type.u32, null)) {
|
||||
@ -21505,15 +21523,15 @@ fn zirReify(
|
||||
const struct_type = ip.loadStructType(ip.typeOf(union_val.val));
|
||||
const len_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
|
||||
ip,
|
||||
try ip.getOrPutString(gpa, "len", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "len", .no_embedded_nulls),
|
||||
).?);
|
||||
const child_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
|
||||
ip,
|
||||
try ip.getOrPutString(gpa, "child", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "child", .no_embedded_nulls),
|
||||
).?);
|
||||
const sentinel_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
|
||||
ip,
|
||||
try ip.getOrPutString(gpa, "sentinel", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "sentinel", .no_embedded_nulls),
|
||||
).?);
|
||||
|
||||
const len = try len_val.toUnsignedIntSema(pt);
|
||||
@ -21534,7 +21552,7 @@ fn zirReify(
|
||||
const struct_type = ip.loadStructType(ip.typeOf(union_val.val));
|
||||
const child_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
|
||||
ip,
|
||||
try ip.getOrPutString(gpa, "child", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "child", .no_embedded_nulls),
|
||||
).?);
|
||||
|
||||
const child_ty = child_val.toType();
|
||||
@ -21546,11 +21564,11 @@ fn zirReify(
|
||||
const struct_type = ip.loadStructType(ip.typeOf(union_val.val));
|
||||
const error_set_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
|
||||
ip,
|
||||
try ip.getOrPutString(gpa, "error_set", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "error_set", .no_embedded_nulls),
|
||||
).?);
|
||||
const payload_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
|
||||
ip,
|
||||
try ip.getOrPutString(gpa, "payload", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "payload", .no_embedded_nulls),
|
||||
).?);
|
||||
|
||||
const error_set_ty = error_set_val.toType();
|
||||
@ -21579,7 +21597,7 @@ fn zirReify(
|
||||
const elem_struct_type = ip.loadStructType(ip.typeOf(elem_val.toIntern()));
|
||||
const name_val = try elem_val.fieldValue(pt, elem_struct_type.nameIndex(
|
||||
ip,
|
||||
try ip.getOrPutString(gpa, "name", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "name", .no_embedded_nulls),
|
||||
).?);
|
||||
|
||||
const name = try sema.sliceToIpString(block, src, name_val, .{
|
||||
@ -21601,23 +21619,23 @@ fn zirReify(
|
||||
const struct_type = ip.loadStructType(ip.typeOf(union_val.val));
|
||||
const layout_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
|
||||
ip,
|
||||
try ip.getOrPutString(gpa, "layout", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "layout", .no_embedded_nulls),
|
||||
).?);
|
||||
const backing_integer_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
|
||||
ip,
|
||||
try ip.getOrPutString(gpa, "backing_integer", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "backing_integer", .no_embedded_nulls),
|
||||
).?);
|
||||
const fields_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
|
||||
ip,
|
||||
try ip.getOrPutString(gpa, "fields", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "fields", .no_embedded_nulls),
|
||||
).?);
|
||||
const decls_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
|
||||
ip,
|
||||
try ip.getOrPutString(gpa, "decls", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "decls", .no_embedded_nulls),
|
||||
).?);
|
||||
const is_tuple_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
|
||||
ip,
|
||||
try ip.getOrPutString(gpa, "is_tuple", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "is_tuple", .no_embedded_nulls),
|
||||
).?);
|
||||
|
||||
const layout = mod.toEnum(std.builtin.Type.ContainerLayout, layout_val);
|
||||
@ -21641,19 +21659,19 @@ fn zirReify(
|
||||
const struct_type = ip.loadStructType(ip.typeOf(union_val.val));
|
||||
const tag_type_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
|
||||
ip,
|
||||
try ip.getOrPutString(gpa, "tag_type", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "tag_type", .no_embedded_nulls),
|
||||
).?);
|
||||
const fields_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
|
||||
ip,
|
||||
try ip.getOrPutString(gpa, "fields", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "fields", .no_embedded_nulls),
|
||||
).?);
|
||||
const decls_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
|
||||
ip,
|
||||
try ip.getOrPutString(gpa, "decls", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "decls", .no_embedded_nulls),
|
||||
).?);
|
||||
const is_exhaustive_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
|
||||
ip,
|
||||
try ip.getOrPutString(gpa, "is_exhaustive", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "is_exhaustive", .no_embedded_nulls),
|
||||
).?);
|
||||
|
||||
if (try decls_val.sliceLen(pt) > 0) {
|
||||
@ -21670,7 +21688,7 @@ fn zirReify(
|
||||
const struct_type = ip.loadStructType(ip.typeOf(union_val.val));
|
||||
const decls_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
|
||||
ip,
|
||||
try ip.getOrPutString(gpa, "decls", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "decls", .no_embedded_nulls),
|
||||
).?);
|
||||
|
||||
// Decls
|
||||
@ -21707,19 +21725,19 @@ fn zirReify(
|
||||
const struct_type = ip.loadStructType(ip.typeOf(union_val.val));
|
||||
const layout_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
|
||||
ip,
|
||||
try ip.getOrPutString(gpa, "layout", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "layout", .no_embedded_nulls),
|
||||
).?);
|
||||
const tag_type_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
|
||||
ip,
|
||||
try ip.getOrPutString(gpa, "tag_type", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "tag_type", .no_embedded_nulls),
|
||||
).?);
|
||||
const fields_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
|
||||
ip,
|
||||
try ip.getOrPutString(gpa, "fields", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "fields", .no_embedded_nulls),
|
||||
).?);
|
||||
const decls_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
|
||||
ip,
|
||||
try ip.getOrPutString(gpa, "decls", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "decls", .no_embedded_nulls),
|
||||
).?);
|
||||
|
||||
if (try decls_val.sliceLen(pt) > 0) {
|
||||
@ -21737,23 +21755,23 @@ fn zirReify(
|
||||
const struct_type = ip.loadStructType(ip.typeOf(union_val.val));
|
||||
const calling_convention_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
|
||||
ip,
|
||||
try ip.getOrPutString(gpa, "calling_convention", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "calling_convention", .no_embedded_nulls),
|
||||
).?);
|
||||
const is_generic_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
|
||||
ip,
|
||||
try ip.getOrPutString(gpa, "is_generic", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "is_generic", .no_embedded_nulls),
|
||||
).?);
|
||||
const is_var_args_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
|
||||
ip,
|
||||
try ip.getOrPutString(gpa, "is_var_args", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "is_var_args", .no_embedded_nulls),
|
||||
).?);
|
||||
const return_type_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
|
||||
ip,
|
||||
try ip.getOrPutString(gpa, "return_type", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "return_type", .no_embedded_nulls),
|
||||
).?);
|
||||
const params_slice_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
|
||||
ip,
|
||||
try ip.getOrPutString(gpa, "params", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "params", .no_embedded_nulls),
|
||||
).?);
|
||||
|
||||
const is_generic = is_generic_val.toBool();
|
||||
@ -21783,15 +21801,15 @@ fn zirReify(
|
||||
const elem_struct_type = ip.loadStructType(ip.typeOf(elem_val.toIntern()));
|
||||
const param_is_generic_val = try elem_val.fieldValue(pt, elem_struct_type.nameIndex(
|
||||
ip,
|
||||
try ip.getOrPutString(gpa, "is_generic", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "is_generic", .no_embedded_nulls),
|
||||
).?);
|
||||
const param_is_noalias_val = try elem_val.fieldValue(pt, elem_struct_type.nameIndex(
|
||||
ip,
|
||||
try ip.getOrPutString(gpa, "is_noalias", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "is_noalias", .no_embedded_nulls),
|
||||
).?);
|
||||
const opt_param_type_val = try elem_val.fieldValue(pt, elem_struct_type.nameIndex(
|
||||
ip,
|
||||
try ip.getOrPutString(gpa, "type", .no_embedded_nulls),
|
||||
try ip.getOrPutString(gpa, pt.tid, "type", .no_embedded_nulls),
|
||||
).?);
|
||||
|
||||
if (param_is_generic_val.toBool()) {
|
||||
@ -22535,7 +22553,7 @@ fn zirTypeName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
const ty_src = block.builtinCallArgSrc(inst_data.src_node, 0);
|
||||
const ty = try sema.resolveType(block, ty_src, inst_data.operand);
|
||||
|
||||
const type_name = try ip.getOrPutStringFmt(sema.gpa, "{}", .{ty.fmt(pt)}, .no_embedded_nulls);
|
||||
const type_name = try ip.getOrPutStringFmt(sema.gpa, pt.tid, "{}", .{ty.fmt(pt)}, .no_embedded_nulls);
|
||||
return sema.addNullTerminatedStrLit(type_name);
|
||||
}
|
||||
|
||||
@ -24143,18 +24161,18 @@ fn resolveExportOptions(
|
||||
const section_src = block.src(.{ .init_field_section = src.offset.node_offset_builtin_call_arg.builtin_call_node });
|
||||
const visibility_src = block.src(.{ .init_field_visibility = src.offset.node_offset_builtin_call_arg.builtin_call_node });
|
||||
|
||||
const name_operand = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, "name", .no_embedded_nulls), name_src);
|
||||
const name_operand = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, pt.tid, "name", .no_embedded_nulls), name_src);
|
||||
const name = try sema.toConstString(block, name_src, name_operand, .{
|
||||
.needed_comptime_reason = "name of exported value must be comptime-known",
|
||||
});
|
||||
|
||||
const linkage_operand = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, "linkage", .no_embedded_nulls), linkage_src);
|
||||
const linkage_operand = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, pt.tid, "linkage", .no_embedded_nulls), linkage_src);
|
||||
const linkage_val = try sema.resolveConstDefinedValue(block, linkage_src, linkage_operand, .{
|
||||
.needed_comptime_reason = "linkage of exported value must be comptime-known",
|
||||
});
|
||||
const linkage = mod.toEnum(std.builtin.GlobalLinkage, linkage_val);
|
||||
|
||||
const section_operand = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, "section", .no_embedded_nulls), section_src);
|
||||
const section_operand = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, pt.tid, "section", .no_embedded_nulls), section_src);
|
||||
const section_opt_val = try sema.resolveConstDefinedValue(block, section_src, section_operand, .{
|
||||
.needed_comptime_reason = "linksection of exported value must be comptime-known",
|
||||
});
|
||||
@ -24165,7 +24183,7 @@ fn resolveExportOptions(
|
||||
else
|
||||
null;
|
||||
|
||||
const visibility_operand = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, "visibility", .no_embedded_nulls), visibility_src);
|
||||
const visibility_operand = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, pt.tid, "visibility", .no_embedded_nulls), visibility_src);
|
||||
const visibility_val = try sema.resolveConstDefinedValue(block, visibility_src, visibility_operand, .{
|
||||
.needed_comptime_reason = "visibility of exported value must be comptime-known",
|
||||
});
|
||||
@ -24182,9 +24200,9 @@ fn resolveExportOptions(
|
||||
}
|
||||
|
||||
return .{
|
||||
.name = try ip.getOrPutString(gpa, name, .no_embedded_nulls),
|
||||
.name = try ip.getOrPutString(gpa, pt.tid, name, .no_embedded_nulls),
|
||||
.linkage = linkage,
|
||||
.section = try ip.getOrPutStringOpt(gpa, section, .no_embedded_nulls),
|
||||
.section = try ip.getOrPutStringOpt(gpa, pt.tid, section, .no_embedded_nulls),
|
||||
.visibility = visibility,
|
||||
};
|
||||
}
|
||||
@ -25821,7 +25839,7 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
|
||||
|
||||
const runtime_src = rs: {
|
||||
const ptr_val = try sema.resolveDefinedValue(block, dest_src, dest_ptr) orelse break :rs dest_src;
|
||||
const len_air_ref = try sema.fieldVal(block, src, dest_ptr, try ip.getOrPutString(gpa, "len", .no_embedded_nulls), dest_src);
|
||||
const len_air_ref = try sema.fieldVal(block, src, dest_ptr, try ip.getOrPutString(gpa, pt.tid, "len", .no_embedded_nulls), dest_src);
|
||||
const len_val = (try sema.resolveDefinedValue(block, dest_src, len_air_ref)) orelse break :rs dest_src;
|
||||
const len_u64 = (try len_val.getUnsignedIntAdvanced(pt, .sema)).?;
|
||||
const len = try sema.usizeCast(block, dest_src, len_u64);
|
||||
@ -25952,7 +25970,7 @@ fn zirVarExtended(
|
||||
.ty = var_ty.toIntern(),
|
||||
.init = init_val,
|
||||
.decl = sema.owner_decl_index,
|
||||
.lib_name = try mod.intern_pool.getOrPutStringOpt(sema.gpa, lib_name, .no_embedded_nulls),
|
||||
.lib_name = try mod.intern_pool.getOrPutStringOpt(sema.gpa, pt.tid, lib_name, .no_embedded_nulls),
|
||||
.is_extern = small.is_extern,
|
||||
.is_const = small.is_const,
|
||||
.is_threadlocal = small.is_threadlocal,
|
||||
@ -26323,17 +26341,17 @@ fn resolvePrefetchOptions(
|
||||
const locality_src = block.src(.{ .init_field_locality = src.offset.node_offset_builtin_call_arg.builtin_call_node });
|
||||
const cache_src = block.src(.{ .init_field_cache = src.offset.node_offset_builtin_call_arg.builtin_call_node });
|
||||
|
||||
const rw = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, "rw", .no_embedded_nulls), rw_src);
|
||||
const rw = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, pt.tid, "rw", .no_embedded_nulls), rw_src);
|
||||
const rw_val = try sema.resolveConstDefinedValue(block, rw_src, rw, .{
|
||||
.needed_comptime_reason = "prefetch read/write must be comptime-known",
|
||||
});
|
||||
|
||||
const locality = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, "locality", .no_embedded_nulls), locality_src);
|
||||
const locality = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, pt.tid, "locality", .no_embedded_nulls), locality_src);
|
||||
const locality_val = try sema.resolveConstDefinedValue(block, locality_src, locality, .{
|
||||
.needed_comptime_reason = "prefetch locality must be comptime-known",
|
||||
});
|
||||
|
||||
const cache = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, "cache", .no_embedded_nulls), cache_src);
|
||||
const cache = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, pt.tid, "cache", .no_embedded_nulls), cache_src);
|
||||
const cache_val = try sema.resolveConstDefinedValue(block, cache_src, cache, .{
|
||||
.needed_comptime_reason = "prefetch cache must be comptime-known",
|
||||
});
|
||||
@ -26397,23 +26415,23 @@ fn resolveExternOptions(
|
||||
const linkage_src = block.src(.{ .init_field_linkage = src.offset.node_offset_builtin_call_arg.builtin_call_node });
|
||||
const thread_local_src = block.src(.{ .init_field_thread_local = src.offset.node_offset_builtin_call_arg.builtin_call_node });
|
||||
|
||||
const name_ref = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, "name", .no_embedded_nulls), name_src);
|
||||
const name_ref = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, pt.tid, "name", .no_embedded_nulls), name_src);
|
||||
const name = try sema.toConstString(block, name_src, name_ref, .{
|
||||
.needed_comptime_reason = "name of the extern symbol must be comptime-known",
|
||||
});
|
||||
|
||||
const library_name_inst = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, "library_name", .no_embedded_nulls), library_src);
|
||||
const library_name_inst = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, pt.tid, "library_name", .no_embedded_nulls), library_src);
|
||||
const library_name_val = try sema.resolveConstDefinedValue(block, library_src, library_name_inst, .{
|
||||
.needed_comptime_reason = "library in which extern symbol is must be comptime-known",
|
||||
});
|
||||
|
||||
const linkage_ref = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, "linkage", .no_embedded_nulls), linkage_src);
|
||||
const linkage_ref = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, pt.tid, "linkage", .no_embedded_nulls), linkage_src);
|
||||
const linkage_val = try sema.resolveConstDefinedValue(block, linkage_src, linkage_ref, .{
|
||||
.needed_comptime_reason = "linkage of the extern symbol must be comptime-known",
|
||||
});
|
||||
const linkage = mod.toEnum(std.builtin.GlobalLinkage, linkage_val);
|
||||
|
||||
const is_thread_local = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, "is_thread_local", .no_embedded_nulls), thread_local_src);
|
||||
const is_thread_local = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, pt.tid, "is_thread_local", .no_embedded_nulls), thread_local_src);
|
||||
const is_thread_local_val = try sema.resolveConstDefinedValue(block, thread_local_src, is_thread_local, .{
|
||||
.needed_comptime_reason = "threadlocality of the extern symbol must be comptime-known",
|
||||
});
|
||||
@ -26438,8 +26456,8 @@ fn resolveExternOptions(
|
||||
}
|
||||
|
||||
return .{
|
||||
.name = try ip.getOrPutString(gpa, name, .no_embedded_nulls),
|
||||
.library_name = try ip.getOrPutStringOpt(gpa, library_name, .no_embedded_nulls),
|
||||
.name = try ip.getOrPutString(gpa, pt.tid, name, .no_embedded_nulls),
|
||||
.library_name = try ip.getOrPutStringOpt(gpa, pt.tid, library_name, .no_embedded_nulls),
|
||||
.linkage = linkage,
|
||||
.is_thread_local = is_thread_local_val.toBool(),
|
||||
};
|
||||
@ -27052,7 +27070,7 @@ fn preparePanicId(sema: *Sema, block: *Block, panic_id: Module.PanicId) !InternP
|
||||
block,
|
||||
LazySrcLoc.unneeded,
|
||||
panic_messages_ty.getNamespaceIndex(mod),
|
||||
try mod.intern_pool.getOrPutString(gpa, @tagName(panic_id), .no_embedded_nulls),
|
||||
try mod.intern_pool.getOrPutString(gpa, pt.tid, @tagName(panic_id), .no_embedded_nulls),
|
||||
) catch |err| switch (err) {
|
||||
error.AnalysisFail => @panic("std.builtin.panic_messages is corrupt"),
|
||||
error.GenericPoison, error.ComptimeReturn, error.ComptimeBreak => unreachable,
|
||||
@ -31745,7 +31763,7 @@ fn coerceTupleToStruct(
|
||||
.anon_struct_type => |anon_struct_type| if (anon_struct_type.names.len > 0)
|
||||
anon_struct_type.names.get(ip)[tuple_field_index]
|
||||
else
|
||||
try ip.getOrPutStringFmt(sema.gpa, "{d}", .{tuple_field_index}, .no_embedded_nulls),
|
||||
try ip.getOrPutStringFmt(sema.gpa, pt.tid, "{d}", .{tuple_field_index}, .no_embedded_nulls),
|
||||
.struct_type => ip.loadStructType(inst_ty.toIntern()).field_names.get(ip)[tuple_field_index],
|
||||
else => unreachable,
|
||||
};
|
||||
@ -31858,13 +31876,13 @@ fn coerceTupleToTuple(
|
||||
.anon_struct_type => |anon_struct_type| if (anon_struct_type.names.len > 0)
|
||||
anon_struct_type.names.get(ip)[field_i]
|
||||
else
|
||||
try ip.getOrPutStringFmt(sema.gpa, "{d}", .{field_i}, .no_embedded_nulls),
|
||||
try ip.getOrPutStringFmt(sema.gpa, pt.tid, "{d}", .{field_i}, .no_embedded_nulls),
|
||||
.struct_type => s: {
|
||||
const struct_type = ip.loadStructType(inst_ty.toIntern());
|
||||
if (struct_type.field_names.len > 0) {
|
||||
break :s struct_type.field_names.get(ip)[field_i];
|
||||
} else {
|
||||
break :s try ip.getOrPutStringFmt(sema.gpa, "{d}", .{field_i}, .no_embedded_nulls);
|
||||
break :s try ip.getOrPutStringFmt(sema.gpa, pt.tid, "{d}", .{field_i}, .no_embedded_nulls);
|
||||
}
|
||||
},
|
||||
else => unreachable,
|
||||
@ -34849,7 +34867,7 @@ fn resolvePeerTypesInner(
|
||||
const result_buf = try sema.arena.create(PeerResolveResult);
|
||||
result_buf.* = result;
|
||||
const field_name = if (is_tuple)
|
||||
try ip.getOrPutStringFmt(sema.gpa, "{d}", .{field_index}, .no_embedded_nulls)
|
||||
try ip.getOrPutStringFmt(sema.gpa, pt.tid, "{d}", .{field_index}, .no_embedded_nulls)
|
||||
else
|
||||
field_names[field_index];
|
||||
|
||||
@ -36066,7 +36084,7 @@ fn semaStructFields(
|
||||
|
||||
// This string needs to outlive the ZIR code.
|
||||
if (opt_field_name_zir) |field_name_zir| {
|
||||
const field_name = try ip.getOrPutString(gpa, field_name_zir, .no_embedded_nulls);
|
||||
const field_name = try ip.getOrPutString(gpa, pt.tid, field_name_zir, .no_embedded_nulls);
|
||||
assert(struct_type.addFieldName(ip, field_name) == null);
|
||||
}
|
||||
|
||||
@ -36567,7 +36585,7 @@ fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_type: InternPool.L
|
||||
}
|
||||
|
||||
// This string needs to outlive the ZIR code.
|
||||
const field_name = try ip.getOrPutString(gpa, field_name_zir, .no_embedded_nulls);
|
||||
const field_name = try ip.getOrPutString(gpa, pt.tid, field_name_zir, .no_embedded_nulls);
|
||||
if (enum_field_names.len != 0) {
|
||||
enum_field_names[field_i] = field_name;
|
||||
}
|
||||
@ -36716,9 +36734,10 @@ fn generateUnionTagTypeNumbered(
|
||||
|
||||
const new_decl_index = try mod.allocateNewDecl(block.namespace);
|
||||
errdefer mod.destroyDecl(new_decl_index);
|
||||
const fqn = try union_owner_decl.fullyQualifiedName(mod);
|
||||
const fqn = try union_owner_decl.fullyQualifiedName(pt);
|
||||
const name = try ip.getOrPutStringFmt(
|
||||
gpa,
|
||||
pt.tid,
|
||||
"@typeInfo({}).Union.tag_type.?",
|
||||
.{fqn.fmt(ip)},
|
||||
.no_embedded_nulls,
|
||||
@ -36764,11 +36783,12 @@ fn generateUnionTagTypeSimple(
|
||||
const gpa = sema.gpa;
|
||||
|
||||
const new_decl_index = new_decl_index: {
|
||||
const fqn = try union_owner_decl.fullyQualifiedName(mod);
|
||||
const fqn = try union_owner_decl.fullyQualifiedName(pt);
|
||||
const new_decl_index = try mod.allocateNewDecl(block.namespace);
|
||||
errdefer mod.destroyDecl(new_decl_index);
|
||||
const name = try ip.getOrPutStringFmt(
|
||||
gpa,
|
||||
pt.tid,
|
||||
"@typeInfo({}).Union.tag_type.?",
|
||||
.{fqn.fmt(ip)},
|
||||
.no_embedded_nulls,
|
||||
|
@ -67,7 +67,7 @@ pub fn toIpString(val: Value, ty: Type, pt: Zcu.PerThread) !InternPool.NullTermi
|
||||
const byte: u8 = @intCast(Value.fromInterned(elem).toUnsignedInt(pt));
|
||||
const len: usize = @intCast(ty.arrayLen(mod));
|
||||
try ip.string_bytes.appendNTimes(mod.gpa, byte, len);
|
||||
return ip.getOrPutTrailingString(mod.gpa, len, .no_embedded_nulls);
|
||||
return ip.getOrPutTrailingString(mod.gpa, pt.tid, len, .no_embedded_nulls);
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -118,7 +118,7 @@ fn arrayToIpString(val: Value, len_u64: u64, pt: Zcu.PerThread) !InternPool.Null
|
||||
const byte: u8 = @intCast(elem_val.toUnsignedInt(pt));
|
||||
ip.string_bytes.appendAssumeCapacity(byte);
|
||||
}
|
||||
return ip.getOrPutTrailingString(gpa, len, .no_embedded_nulls);
|
||||
return ip.getOrPutTrailingString(gpa, pt.tid, len, .no_embedded_nulls);
|
||||
}
|
||||
|
||||
pub fn fromInterned(i: InternPool.Index) Value {
|
||||
|
687
src/Zcu.zig
687
src/Zcu.zig
@ -420,11 +420,11 @@ pub const Decl = struct {
|
||||
return zcu.namespacePtr(decl.src_namespace).renderFullyQualifiedDebugName(zcu, decl.name, writer);
|
||||
}
|
||||
|
||||
pub fn fullyQualifiedName(decl: Decl, zcu: *Zcu) !InternPool.NullTerminatedString {
|
||||
pub fn fullyQualifiedName(decl: Decl, pt: Zcu.PerThread) !InternPool.NullTerminatedString {
|
||||
return if (decl.name_fully_qualified)
|
||||
decl.name
|
||||
else
|
||||
zcu.namespacePtr(decl.src_namespace).fullyQualifiedName(zcu, decl.name);
|
||||
pt.zcu.namespacePtr(decl.src_namespace).fullyQualifiedName(pt, decl.name);
|
||||
}
|
||||
|
||||
pub fn typeOf(decl: Decl, zcu: *const Zcu) Type {
|
||||
@ -688,9 +688,10 @@ pub const Namespace = struct {
|
||||
|
||||
pub fn fullyQualifiedName(
|
||||
ns: Namespace,
|
||||
zcu: *Zcu,
|
||||
pt: Zcu.PerThread,
|
||||
name: InternPool.NullTerminatedString,
|
||||
) !InternPool.NullTerminatedString {
|
||||
const zcu = pt.zcu;
|
||||
const ip = &zcu.intern_pool;
|
||||
const count = count: {
|
||||
var count: usize = name.length(ip) + 1;
|
||||
@ -723,7 +724,7 @@ pub const Namespace = struct {
|
||||
};
|
||||
}
|
||||
|
||||
return ip.getOrPutTrailingString(gpa, ip.string_bytes.items.len - start, .no_embedded_nulls);
|
||||
return ip.getOrPutTrailingString(gpa, pt.tid, ip.string_bytes.items.len - start, .no_embedded_nulls);
|
||||
}
|
||||
|
||||
pub fn getType(ns: Namespace, zcu: *Zcu) Type {
|
||||
@ -875,11 +876,12 @@ pub const File = struct {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn fullyQualifiedName(file: File, mod: *Module) !InternPool.NullTerminatedString {
|
||||
const ip = &mod.intern_pool;
|
||||
pub fn fullyQualifiedName(file: File, pt: Zcu.PerThread) !InternPool.NullTerminatedString {
|
||||
const gpa = pt.zcu.gpa;
|
||||
const ip = &pt.zcu.intern_pool;
|
||||
const start = ip.string_bytes.items.len;
|
||||
try file.renderFullyQualifiedName(ip.string_bytes.writer(mod.gpa));
|
||||
return ip.getOrPutTrailingString(mod.gpa, ip.string_bytes.items.len - start, .no_embedded_nulls);
|
||||
try file.renderFullyQualifiedName(ip.string_bytes.writer(gpa));
|
||||
return ip.getOrPutTrailingString(gpa, pt.tid, ip.string_bytes.items.len - start, .no_embedded_nulls);
|
||||
}
|
||||
|
||||
pub fn fullPath(file: File, ally: Allocator) ![]u8 {
|
||||
@ -2569,8 +2571,8 @@ pub fn declIsRoot(mod: *Module, decl_index: Decl.Index) bool {
|
||||
}
|
||||
|
||||
// TODO https://github.com/ziglang/zig/issues/8643
|
||||
const data_has_safety_tag = @sizeOf(Zir.Inst.Data) != 8;
|
||||
const HackDataLayout = extern struct {
|
||||
pub const data_has_safety_tag = @sizeOf(Zir.Inst.Data) != 8;
|
||||
pub const HackDataLayout = extern struct {
|
||||
data: [8]u8 align(@alignOf(Zir.Inst.Data)),
|
||||
safety_tag: u8,
|
||||
};
|
||||
@ -2580,291 +2582,11 @@ comptime {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn astGenFile(
|
||||
zcu: *Zcu,
|
||||
file: *File,
|
||||
/// This parameter is provided separately from `file` because it is not
|
||||
/// safe to access `import_table` without a lock, and this index is needed
|
||||
/// in the call to `updateZirRefs`.
|
||||
file_index: File.Index,
|
||||
path_digest: Cache.BinDigest,
|
||||
opt_root_decl: Zcu.Decl.OptionalIndex,
|
||||
) !void {
|
||||
assert(!file.mod.isBuiltin());
|
||||
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
const comp = zcu.comp;
|
||||
const gpa = zcu.gpa;
|
||||
|
||||
// In any case we need to examine the stat of the file to determine the course of action.
|
||||
var source_file = try file.mod.root.openFile(file.sub_file_path, .{});
|
||||
defer source_file.close();
|
||||
|
||||
const stat = try source_file.stat();
|
||||
|
||||
const want_local_cache = file.mod == zcu.main_mod;
|
||||
const hex_digest = Cache.binToHex(path_digest);
|
||||
const cache_directory = if (want_local_cache) zcu.local_zir_cache else zcu.global_zir_cache;
|
||||
const zir_dir = cache_directory.handle;
|
||||
|
||||
// Determine whether we need to reload the file from disk and redo parsing and AstGen.
|
||||
var lock: std.fs.File.Lock = switch (file.status) {
|
||||
.never_loaded, .retryable_failure => lock: {
|
||||
// First, load the cached ZIR code, if any.
|
||||
log.debug("AstGen checking cache: {s} (local={}, digest={s})", .{
|
||||
file.sub_file_path, want_local_cache, &hex_digest,
|
||||
});
|
||||
|
||||
break :lock .shared;
|
||||
},
|
||||
.parse_failure, .astgen_failure, .success_zir => lock: {
|
||||
const unchanged_metadata =
|
||||
stat.size == file.stat.size and
|
||||
stat.mtime == file.stat.mtime and
|
||||
stat.inode == file.stat.inode;
|
||||
|
||||
if (unchanged_metadata) {
|
||||
log.debug("unmodified metadata of file: {s}", .{file.sub_file_path});
|
||||
return;
|
||||
}
|
||||
|
||||
log.debug("metadata changed: {s}", .{file.sub_file_path});
|
||||
|
||||
break :lock .exclusive;
|
||||
},
|
||||
};
|
||||
|
||||
// We ask for a lock in order to coordinate with other zig processes.
|
||||
// If another process is already working on this file, we will get the cached
|
||||
// version. Likewise if we're working on AstGen and another process asks for
|
||||
// the cached file, they'll get it.
|
||||
const cache_file = while (true) {
|
||||
break zir_dir.createFile(&hex_digest, .{
|
||||
.read = true,
|
||||
.truncate = false,
|
||||
.lock = lock,
|
||||
}) catch |err| switch (err) {
|
||||
error.NotDir => unreachable, // no dir components
|
||||
error.InvalidUtf8 => unreachable, // it's a hex encoded name
|
||||
error.InvalidWtf8 => unreachable, // it's a hex encoded name
|
||||
error.BadPathName => unreachable, // it's a hex encoded name
|
||||
error.NameTooLong => unreachable, // it's a fixed size name
|
||||
error.PipeBusy => unreachable, // it's not a pipe
|
||||
error.WouldBlock => unreachable, // not asking for non-blocking I/O
|
||||
// There are no dir components, so you would think that this was
|
||||
// unreachable, however we have observed on macOS two processes racing
|
||||
// to do openat() with O_CREAT manifest in ENOENT.
|
||||
error.FileNotFound => continue,
|
||||
|
||||
else => |e| return e, // Retryable errors are handled at callsite.
|
||||
};
|
||||
};
|
||||
defer cache_file.close();
|
||||
|
||||
while (true) {
|
||||
update: {
|
||||
// First we read the header to determine the lengths of arrays.
|
||||
const header = cache_file.reader().readStruct(Zir.Header) catch |err| switch (err) {
|
||||
// This can happen if Zig bails out of this function between creating
|
||||
// the cached file and writing it.
|
||||
error.EndOfStream => break :update,
|
||||
else => |e| return e,
|
||||
};
|
||||
const unchanged_metadata =
|
||||
stat.size == header.stat_size and
|
||||
stat.mtime == header.stat_mtime and
|
||||
stat.inode == header.stat_inode;
|
||||
|
||||
if (!unchanged_metadata) {
|
||||
log.debug("AstGen cache stale: {s}", .{file.sub_file_path});
|
||||
break :update;
|
||||
}
|
||||
log.debug("AstGen cache hit: {s} instructions_len={d}", .{
|
||||
file.sub_file_path, header.instructions_len,
|
||||
});
|
||||
|
||||
file.zir = loadZirCacheBody(gpa, header, cache_file) catch |err| switch (err) {
|
||||
error.UnexpectedFileSize => {
|
||||
log.warn("unexpected EOF reading cached ZIR for {s}", .{file.sub_file_path});
|
||||
break :update;
|
||||
},
|
||||
else => |e| return e,
|
||||
};
|
||||
file.zir_loaded = true;
|
||||
file.stat = .{
|
||||
.size = header.stat_size,
|
||||
.inode = header.stat_inode,
|
||||
.mtime = header.stat_mtime,
|
||||
};
|
||||
file.status = .success_zir;
|
||||
log.debug("AstGen cached success: {s}", .{file.sub_file_path});
|
||||
|
||||
// TODO don't report compile errors until Sema @importFile
|
||||
if (file.zir.hasCompileErrors()) {
|
||||
{
|
||||
comp.mutex.lock();
|
||||
defer comp.mutex.unlock();
|
||||
try zcu.failed_files.putNoClobber(gpa, file, null);
|
||||
}
|
||||
file.status = .astgen_failure;
|
||||
return error.AnalysisFail;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// If we already have the exclusive lock then it is our job to update.
|
||||
if (builtin.os.tag == .wasi or lock == .exclusive) break;
|
||||
// Otherwise, unlock to give someone a chance to get the exclusive lock
|
||||
// and then upgrade to an exclusive lock.
|
||||
cache_file.unlock();
|
||||
lock = .exclusive;
|
||||
try cache_file.lock(lock);
|
||||
}
|
||||
|
||||
// The cache is definitely stale so delete the contents to avoid an underwrite later.
|
||||
cache_file.setEndPos(0) catch |err| switch (err) {
|
||||
error.FileTooBig => unreachable, // 0 is not too big
|
||||
|
||||
else => |e| return e,
|
||||
};
|
||||
|
||||
zcu.lockAndClearFileCompileError(file);
|
||||
|
||||
// If the previous ZIR does not have compile errors, keep it around
|
||||
// in case parsing or new ZIR fails. In case of successful ZIR update
|
||||
// at the end of this function we will free it.
|
||||
// We keep the previous ZIR loaded so that we can use it
|
||||
// for the update next time it does not have any compile errors. This avoids
|
||||
// needlessly tossing out semantic analysis work when an error is
|
||||
// temporarily introduced.
|
||||
if (file.zir_loaded and !file.zir.hasCompileErrors()) {
|
||||
assert(file.prev_zir == null);
|
||||
const prev_zir_ptr = try gpa.create(Zir);
|
||||
file.prev_zir = prev_zir_ptr;
|
||||
prev_zir_ptr.* = file.zir;
|
||||
file.zir = undefined;
|
||||
file.zir_loaded = false;
|
||||
}
|
||||
file.unload(gpa);
|
||||
|
||||
if (stat.size > std.math.maxInt(u32))
|
||||
return error.FileTooBig;
|
||||
|
||||
const source = try gpa.allocSentinel(u8, @as(usize, @intCast(stat.size)), 0);
|
||||
defer if (!file.source_loaded) gpa.free(source);
|
||||
const amt = try source_file.readAll(source);
|
||||
if (amt != stat.size)
|
||||
return error.UnexpectedEndOfFile;
|
||||
|
||||
file.stat = .{
|
||||
.size = stat.size,
|
||||
.inode = stat.inode,
|
||||
.mtime = stat.mtime,
|
||||
};
|
||||
file.source = source;
|
||||
file.source_loaded = true;
|
||||
|
||||
file.tree = try Ast.parse(gpa, source, .zig);
|
||||
file.tree_loaded = true;
|
||||
|
||||
// Any potential AST errors are converted to ZIR errors here.
|
||||
file.zir = try AstGen.generate(gpa, file.tree);
|
||||
file.zir_loaded = true;
|
||||
file.status = .success_zir;
|
||||
log.debug("AstGen fresh success: {s}", .{file.sub_file_path});
|
||||
|
||||
const safety_buffer = if (data_has_safety_tag)
|
||||
try gpa.alloc([8]u8, file.zir.instructions.len)
|
||||
else
|
||||
undefined;
|
||||
defer if (data_has_safety_tag) gpa.free(safety_buffer);
|
||||
const data_ptr = if (data_has_safety_tag)
|
||||
if (file.zir.instructions.len == 0)
|
||||
@as([*]const u8, undefined)
|
||||
else
|
||||
@as([*]const u8, @ptrCast(safety_buffer.ptr))
|
||||
else
|
||||
@as([*]const u8, @ptrCast(file.zir.instructions.items(.data).ptr));
|
||||
if (data_has_safety_tag) {
|
||||
// The `Data` union has a safety tag but in the file format we store it without.
|
||||
for (file.zir.instructions.items(.data), 0..) |*data, i| {
|
||||
const as_struct = @as(*const HackDataLayout, @ptrCast(data));
|
||||
safety_buffer[i] = as_struct.data;
|
||||
}
|
||||
}
|
||||
|
||||
const header: Zir.Header = .{
|
||||
.instructions_len = @as(u32, @intCast(file.zir.instructions.len)),
|
||||
.string_bytes_len = @as(u32, @intCast(file.zir.string_bytes.len)),
|
||||
.extra_len = @as(u32, @intCast(file.zir.extra.len)),
|
||||
|
||||
.stat_size = stat.size,
|
||||
.stat_inode = stat.inode,
|
||||
.stat_mtime = stat.mtime,
|
||||
};
|
||||
var iovecs = [_]std.posix.iovec_const{
|
||||
.{
|
||||
.base = @as([*]const u8, @ptrCast(&header)),
|
||||
.len = @sizeOf(Zir.Header),
|
||||
},
|
||||
.{
|
||||
.base = @as([*]const u8, @ptrCast(file.zir.instructions.items(.tag).ptr)),
|
||||
.len = file.zir.instructions.len,
|
||||
},
|
||||
.{
|
||||
.base = data_ptr,
|
||||
.len = file.zir.instructions.len * 8,
|
||||
},
|
||||
.{
|
||||
.base = file.zir.string_bytes.ptr,
|
||||
.len = file.zir.string_bytes.len,
|
||||
},
|
||||
.{
|
||||
.base = @as([*]const u8, @ptrCast(file.zir.extra.ptr)),
|
||||
.len = file.zir.extra.len * 4,
|
||||
},
|
||||
};
|
||||
cache_file.writevAll(&iovecs) catch |err| {
|
||||
log.warn("unable to write cached ZIR code for {}{s} to {}{s}: {s}", .{
|
||||
file.mod.root, file.sub_file_path, cache_directory, &hex_digest, @errorName(err),
|
||||
});
|
||||
};
|
||||
|
||||
if (file.zir.hasCompileErrors()) {
|
||||
{
|
||||
comp.mutex.lock();
|
||||
defer comp.mutex.unlock();
|
||||
try zcu.failed_files.putNoClobber(gpa, file, null);
|
||||
}
|
||||
file.status = .astgen_failure;
|
||||
return error.AnalysisFail;
|
||||
}
|
||||
|
||||
if (file.prev_zir) |prev_zir| {
|
||||
try updateZirRefs(zcu, file, file_index, prev_zir.*);
|
||||
// No need to keep previous ZIR.
|
||||
prev_zir.deinit(gpa);
|
||||
gpa.destroy(prev_zir);
|
||||
file.prev_zir = null;
|
||||
}
|
||||
|
||||
if (opt_root_decl.unwrap()) |root_decl| {
|
||||
// The root of this file must be re-analyzed, since the file has changed.
|
||||
comp.mutex.lock();
|
||||
defer comp.mutex.unlock();
|
||||
|
||||
log.debug("outdated root Decl: {}", .{root_decl});
|
||||
try zcu.outdated_file_root.put(gpa, root_decl, {});
|
||||
}
|
||||
}
|
||||
|
||||
pub fn loadZirCache(gpa: Allocator, cache_file: std.fs.File) !Zir {
|
||||
return loadZirCacheBody(gpa, try cache_file.reader().readStruct(Zir.Header), cache_file);
|
||||
}
|
||||
|
||||
fn loadZirCacheBody(gpa: Allocator, header: Zir.Header, cache_file: std.fs.File) !Zir {
|
||||
pub fn loadZirCacheBody(gpa: Allocator, header: Zir.Header, cache_file: std.fs.File) !Zir {
|
||||
var instructions: std.MultiArrayList(Zir.Inst) = .{};
|
||||
errdefer instructions.deinit(gpa);
|
||||
|
||||
@ -2930,127 +2652,6 @@ fn loadZirCacheBody(gpa: Allocator, header: Zir.Header, cache_file: std.fs.File)
|
||||
return zir;
|
||||
}
|
||||
|
||||
/// This is called from the AstGen thread pool, so must acquire
|
||||
/// the Compilation mutex when acting on shared state.
|
||||
fn updateZirRefs(zcu: *Module, file: *File, file_index: File.Index, old_zir: Zir) !void {
|
||||
const gpa = zcu.gpa;
|
||||
const new_zir = file.zir;
|
||||
|
||||
var inst_map: std.AutoHashMapUnmanaged(Zir.Inst.Index, Zir.Inst.Index) = .{};
|
||||
defer inst_map.deinit(gpa);
|
||||
|
||||
try mapOldZirToNew(gpa, old_zir, new_zir, &inst_map);
|
||||
|
||||
const old_tag = old_zir.instructions.items(.tag);
|
||||
const old_data = old_zir.instructions.items(.data);
|
||||
|
||||
// TODO: this should be done after all AstGen workers complete, to avoid
|
||||
// iterating over this full set for every updated file.
|
||||
for (zcu.intern_pool.tracked_insts.keys(), 0..) |*ti, idx_raw| {
|
||||
const ti_idx: InternPool.TrackedInst.Index = @enumFromInt(idx_raw);
|
||||
if (ti.file != file_index) continue;
|
||||
const old_inst = ti.inst;
|
||||
ti.inst = inst_map.get(ti.inst) orelse {
|
||||
// Tracking failed for this instruction. Invalidate associated `src_hash` deps.
|
||||
zcu.comp.mutex.lock();
|
||||
defer zcu.comp.mutex.unlock();
|
||||
log.debug("tracking failed for %{d}", .{old_inst});
|
||||
try zcu.markDependeeOutdated(.{ .src_hash = ti_idx });
|
||||
continue;
|
||||
};
|
||||
|
||||
if (old_zir.getAssociatedSrcHash(old_inst)) |old_hash| hash_changed: {
|
||||
if (new_zir.getAssociatedSrcHash(ti.inst)) |new_hash| {
|
||||
if (std.zig.srcHashEql(old_hash, new_hash)) {
|
||||
break :hash_changed;
|
||||
}
|
||||
log.debug("hash for (%{d} -> %{d}) changed: {} -> {}", .{
|
||||
old_inst,
|
||||
ti.inst,
|
||||
std.fmt.fmtSliceHexLower(&old_hash),
|
||||
std.fmt.fmtSliceHexLower(&new_hash),
|
||||
});
|
||||
}
|
||||
// The source hash associated with this instruction changed - invalidate relevant dependencies.
|
||||
zcu.comp.mutex.lock();
|
||||
defer zcu.comp.mutex.unlock();
|
||||
try zcu.markDependeeOutdated(.{ .src_hash = ti_idx });
|
||||
}
|
||||
|
||||
// If this is a `struct_decl` etc, we must invalidate any outdated namespace dependencies.
|
||||
const has_namespace = switch (old_tag[@intFromEnum(old_inst)]) {
|
||||
.extended => switch (old_data[@intFromEnum(old_inst)].extended.opcode) {
|
||||
.struct_decl, .union_decl, .opaque_decl, .enum_decl => true,
|
||||
else => false,
|
||||
},
|
||||
else => false,
|
||||
};
|
||||
if (!has_namespace) continue;
|
||||
|
||||
var old_names: std.AutoArrayHashMapUnmanaged(InternPool.NullTerminatedString, void) = .{};
|
||||
defer old_names.deinit(zcu.gpa);
|
||||
{
|
||||
var it = old_zir.declIterator(old_inst);
|
||||
while (it.next()) |decl_inst| {
|
||||
const decl_name = old_zir.getDeclaration(decl_inst)[0].name;
|
||||
switch (decl_name) {
|
||||
.@"comptime", .@"usingnamespace", .unnamed_test, .decltest => continue,
|
||||
_ => if (decl_name.isNamedTest(old_zir)) continue,
|
||||
}
|
||||
const name_zir = decl_name.toString(old_zir).?;
|
||||
const name_ip = try zcu.intern_pool.getOrPutString(
|
||||
zcu.gpa,
|
||||
old_zir.nullTerminatedString(name_zir),
|
||||
.no_embedded_nulls,
|
||||
);
|
||||
try old_names.put(zcu.gpa, name_ip, {});
|
||||
}
|
||||
}
|
||||
var any_change = false;
|
||||
{
|
||||
var it = new_zir.declIterator(ti.inst);
|
||||
while (it.next()) |decl_inst| {
|
||||
const decl_name = old_zir.getDeclaration(decl_inst)[0].name;
|
||||
switch (decl_name) {
|
||||
.@"comptime", .@"usingnamespace", .unnamed_test, .decltest => continue,
|
||||
_ => if (decl_name.isNamedTest(old_zir)) continue,
|
||||
}
|
||||
const name_zir = decl_name.toString(old_zir).?;
|
||||
const name_ip = try zcu.intern_pool.getOrPutString(
|
||||
zcu.gpa,
|
||||
old_zir.nullTerminatedString(name_zir),
|
||||
.no_embedded_nulls,
|
||||
);
|
||||
if (!old_names.swapRemove(name_ip)) continue;
|
||||
// Name added
|
||||
any_change = true;
|
||||
zcu.comp.mutex.lock();
|
||||
defer zcu.comp.mutex.unlock();
|
||||
try zcu.markDependeeOutdated(.{ .namespace_name = .{
|
||||
.namespace = ti_idx,
|
||||
.name = name_ip,
|
||||
} });
|
||||
}
|
||||
}
|
||||
// The only elements remaining in `old_names` now are any names which were removed.
|
||||
for (old_names.keys()) |name_ip| {
|
||||
any_change = true;
|
||||
zcu.comp.mutex.lock();
|
||||
defer zcu.comp.mutex.unlock();
|
||||
try zcu.markDependeeOutdated(.{ .namespace_name = .{
|
||||
.namespace = ti_idx,
|
||||
.name = name_ip,
|
||||
} });
|
||||
}
|
||||
|
||||
if (any_change) {
|
||||
zcu.comp.mutex.lock();
|
||||
defer zcu.comp.mutex.unlock();
|
||||
try zcu.markDependeeOutdated(.{ .namespace = ti_idx });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn markDependeeOutdated(zcu: *Zcu, dependee: InternPool.Dependee) !void {
|
||||
log.debug("outdated dependee: {}", .{dependee});
|
||||
var it = zcu.intern_pool.dependencyIterator(dependee);
|
||||
@ -3695,268 +3296,6 @@ fn computePathDigest(zcu: *Zcu, mod: *Package.Module, sub_file_path: []const u8)
|
||||
return bin;
|
||||
}
|
||||
|
||||
pub fn scanNamespace(
|
||||
zcu: *Zcu,
|
||||
namespace_index: Namespace.Index,
|
||||
decls: []const Zir.Inst.Index,
|
||||
parent_decl: *Decl,
|
||||
) Allocator.Error!void {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
const gpa = zcu.gpa;
|
||||
const namespace = zcu.namespacePtr(namespace_index);
|
||||
|
||||
// For incremental updates, `scanDecl` wants to look up existing decls by their ZIR index rather
|
||||
// than their name. We'll build an efficient mapping now, then discard the current `decls`.
|
||||
var existing_by_inst: std.AutoHashMapUnmanaged(InternPool.TrackedInst.Index, Decl.Index) = .{};
|
||||
defer existing_by_inst.deinit(gpa);
|
||||
|
||||
try existing_by_inst.ensureTotalCapacity(gpa, @intCast(namespace.decls.count()));
|
||||
|
||||
for (namespace.decls.keys()) |decl_index| {
|
||||
const decl = zcu.declPtr(decl_index);
|
||||
existing_by_inst.putAssumeCapacityNoClobber(decl.zir_decl_index.unwrap().?, decl_index);
|
||||
}
|
||||
|
||||
var seen_decls: std.AutoHashMapUnmanaged(InternPool.NullTerminatedString, void) = .{};
|
||||
defer seen_decls.deinit(gpa);
|
||||
|
||||
try zcu.comp.work_queue.ensureUnusedCapacity(decls.len);
|
||||
|
||||
namespace.decls.clearRetainingCapacity();
|
||||
try namespace.decls.ensureTotalCapacity(gpa, decls.len);
|
||||
|
||||
namespace.usingnamespace_set.clearRetainingCapacity();
|
||||
|
||||
var scan_decl_iter: ScanDeclIter = .{
|
||||
.zcu = zcu,
|
||||
.namespace_index = namespace_index,
|
||||
.parent_decl = parent_decl,
|
||||
.seen_decls = &seen_decls,
|
||||
.existing_by_inst = &existing_by_inst,
|
||||
.pass = .named,
|
||||
};
|
||||
for (decls) |decl_inst| {
|
||||
try scanDecl(&scan_decl_iter, decl_inst);
|
||||
}
|
||||
scan_decl_iter.pass = .unnamed;
|
||||
for (decls) |decl_inst| {
|
||||
try scanDecl(&scan_decl_iter, decl_inst);
|
||||
}
|
||||
|
||||
if (seen_decls.count() != namespace.decls.count()) {
|
||||
// Do a pass over the namespace contents and remove any decls from the last update
|
||||
// which were removed in this one.
|
||||
var i: usize = 0;
|
||||
while (i < namespace.decls.count()) {
|
||||
const decl_index = namespace.decls.keys()[i];
|
||||
const decl = zcu.declPtr(decl_index);
|
||||
if (!seen_decls.contains(decl.name)) {
|
||||
// We must preserve namespace ordering for @typeInfo.
|
||||
namespace.decls.orderedRemoveAt(i);
|
||||
i -= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const ScanDeclIter = struct {
|
||||
zcu: *Zcu,
|
||||
namespace_index: Namespace.Index,
|
||||
parent_decl: *Decl,
|
||||
seen_decls: *std.AutoHashMapUnmanaged(InternPool.NullTerminatedString, void),
|
||||
existing_by_inst: *const std.AutoHashMapUnmanaged(InternPool.TrackedInst.Index, Decl.Index),
|
||||
/// Decl scanning is run in two passes, so that we can detect when a generated
|
||||
/// name would clash with an explicit name and use a different one.
|
||||
pass: enum { named, unnamed },
|
||||
usingnamespace_index: usize = 0,
|
||||
comptime_index: usize = 0,
|
||||
unnamed_test_index: usize = 0,
|
||||
|
||||
fn avoidNameConflict(iter: *ScanDeclIter, comptime fmt: []const u8, args: anytype) !InternPool.NullTerminatedString {
|
||||
const zcu = iter.zcu;
|
||||
const gpa = zcu.gpa;
|
||||
const ip = &zcu.intern_pool;
|
||||
var name = try ip.getOrPutStringFmt(gpa, fmt, args, .no_embedded_nulls);
|
||||
var gop = try iter.seen_decls.getOrPut(gpa, name);
|
||||
var next_suffix: u32 = 0;
|
||||
while (gop.found_existing) {
|
||||
name = try ip.getOrPutStringFmt(gpa, "{}_{d}", .{ name.fmt(ip), next_suffix }, .no_embedded_nulls);
|
||||
gop = try iter.seen_decls.getOrPut(gpa, name);
|
||||
next_suffix += 1;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
};
|
||||
|
||||
fn scanDecl(iter: *ScanDeclIter, decl_inst: Zir.Inst.Index) Allocator.Error!void {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
const zcu = iter.zcu;
|
||||
const namespace_index = iter.namespace_index;
|
||||
const namespace = zcu.namespacePtr(namespace_index);
|
||||
const gpa = zcu.gpa;
|
||||
const zir = namespace.fileScope(zcu).zir;
|
||||
const ip = &zcu.intern_pool;
|
||||
|
||||
const inst_data = zir.instructions.items(.data)[@intFromEnum(decl_inst)].declaration;
|
||||
const extra = zir.extraData(Zir.Inst.Declaration, inst_data.payload_index);
|
||||
const declaration = extra.data;
|
||||
|
||||
// Every Decl needs a name.
|
||||
const decl_name: InternPool.NullTerminatedString, const kind: Decl.Kind, const is_named_test: bool = switch (declaration.name) {
|
||||
.@"comptime" => info: {
|
||||
if (iter.pass != .unnamed) return;
|
||||
const i = iter.comptime_index;
|
||||
iter.comptime_index += 1;
|
||||
break :info .{
|
||||
try iter.avoidNameConflict("comptime_{d}", .{i}),
|
||||
.@"comptime",
|
||||
false,
|
||||
};
|
||||
},
|
||||
.@"usingnamespace" => info: {
|
||||
// TODO: this isn't right! These should be considered unnamed. Name conflicts can happen here.
|
||||
// The problem is, we need to preserve the decl ordering for `@typeInfo`.
|
||||
// I'm not bothering to fix this now, since some upcoming changes will change this code significantly anyway.
|
||||
if (iter.pass != .named) return;
|
||||
const i = iter.usingnamespace_index;
|
||||
iter.usingnamespace_index += 1;
|
||||
break :info .{
|
||||
try iter.avoidNameConflict("usingnamespace_{d}", .{i}),
|
||||
.@"usingnamespace",
|
||||
false,
|
||||
};
|
||||
},
|
||||
.unnamed_test => info: {
|
||||
if (iter.pass != .unnamed) return;
|
||||
const i = iter.unnamed_test_index;
|
||||
iter.unnamed_test_index += 1;
|
||||
break :info .{
|
||||
try iter.avoidNameConflict("test_{d}", .{i}),
|
||||
.@"test",
|
||||
false,
|
||||
};
|
||||
},
|
||||
.decltest => info: {
|
||||
// We consider these to be unnamed since the decl name can be adjusted to avoid conflicts if necessary.
|
||||
if (iter.pass != .unnamed) return;
|
||||
assert(declaration.flags.has_doc_comment);
|
||||
const name = zir.nullTerminatedString(@enumFromInt(zir.extra[extra.end]));
|
||||
break :info .{
|
||||
try iter.avoidNameConflict("decltest.{s}", .{name}),
|
||||
.@"test",
|
||||
true,
|
||||
};
|
||||
},
|
||||
_ => if (declaration.name.isNamedTest(zir)) info: {
|
||||
// We consider these to be unnamed since the decl name can be adjusted to avoid conflicts if necessary.
|
||||
if (iter.pass != .unnamed) return;
|
||||
break :info .{
|
||||
try iter.avoidNameConflict("test.{s}", .{zir.nullTerminatedString(declaration.name.toString(zir).?)}),
|
||||
.@"test",
|
||||
true,
|
||||
};
|
||||
} else info: {
|
||||
if (iter.pass != .named) return;
|
||||
const name = try ip.getOrPutString(
|
||||
gpa,
|
||||
zir.nullTerminatedString(declaration.name.toString(zir).?),
|
||||
.no_embedded_nulls,
|
||||
);
|
||||
try iter.seen_decls.putNoClobber(gpa, name, {});
|
||||
break :info .{
|
||||
name,
|
||||
.named,
|
||||
false,
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
switch (kind) {
|
||||
.@"usingnamespace" => try namespace.usingnamespace_set.ensureUnusedCapacity(gpa, 1),
|
||||
.@"test" => try zcu.test_functions.ensureUnusedCapacity(gpa, 1),
|
||||
else => {},
|
||||
}
|
||||
|
||||
const parent_file_scope_index = iter.parent_decl.getFileScopeIndex(zcu);
|
||||
const tracked_inst = try ip.trackZir(gpa, parent_file_scope_index, decl_inst);
|
||||
|
||||
// We create a Decl for it regardless of analysis status.
|
||||
|
||||
const prev_exported, const decl_index = if (iter.existing_by_inst.get(tracked_inst)) |decl_index| decl_index: {
|
||||
// We need only update this existing Decl.
|
||||
const decl = zcu.declPtr(decl_index);
|
||||
const was_exported = decl.is_exported;
|
||||
assert(decl.kind == kind); // ZIR tracking should preserve this
|
||||
decl.name = decl_name;
|
||||
decl.is_pub = declaration.flags.is_pub;
|
||||
decl.is_exported = declaration.flags.is_export;
|
||||
break :decl_index .{ was_exported, decl_index };
|
||||
} else decl_index: {
|
||||
// Create and set up a new Decl.
|
||||
const new_decl_index = try zcu.allocateNewDecl(namespace_index);
|
||||
const new_decl = zcu.declPtr(new_decl_index);
|
||||
new_decl.kind = kind;
|
||||
new_decl.name = decl_name;
|
||||
new_decl.is_pub = declaration.flags.is_pub;
|
||||
new_decl.is_exported = declaration.flags.is_export;
|
||||
new_decl.zir_decl_index = tracked_inst.toOptional();
|
||||
break :decl_index .{ false, new_decl_index };
|
||||
};
|
||||
|
||||
const decl = zcu.declPtr(decl_index);
|
||||
|
||||
namespace.decls.putAssumeCapacityNoClobberContext(decl_index, {}, .{ .zcu = zcu });
|
||||
|
||||
const comp = zcu.comp;
|
||||
const decl_mod = namespace.fileScope(zcu).mod;
|
||||
const want_analysis = declaration.flags.is_export or switch (kind) {
|
||||
.anon => unreachable,
|
||||
.@"comptime" => true,
|
||||
.@"usingnamespace" => a: {
|
||||
namespace.usingnamespace_set.putAssumeCapacityNoClobber(decl_index, declaration.flags.is_pub);
|
||||
break :a true;
|
||||
},
|
||||
.named => false,
|
||||
.@"test" => a: {
|
||||
if (!comp.config.is_test) break :a false;
|
||||
if (decl_mod != zcu.main_mod) break :a false;
|
||||
if (is_named_test and comp.test_filters.len > 0) {
|
||||
const decl_fqn = try namespace.fullyQualifiedName(zcu, decl_name);
|
||||
const decl_fqn_slice = decl_fqn.toSlice(ip);
|
||||
for (comp.test_filters) |test_filter| {
|
||||
if (mem.indexOf(u8, decl_fqn_slice, test_filter)) |_| break;
|
||||
} else break :a false;
|
||||
}
|
||||
zcu.test_functions.putAssumeCapacity(decl_index, {}); // may clobber on incremental update
|
||||
break :a true;
|
||||
},
|
||||
};
|
||||
|
||||
if (want_analysis) {
|
||||
// We will not queue analysis if the decl has been analyzed on a previous update and
|
||||
// `is_export` is unchanged. In this case, the incremental update mechanism will handle
|
||||
// re-analysis for us if necessary.
|
||||
if (prev_exported != declaration.flags.is_export or decl.analysis == .unreferenced) {
|
||||
log.debug("scanDecl queue analyze_decl file='{s}' decl_name='{}' decl_index={d}", .{
|
||||
namespace.fileScope(zcu).sub_file_path, decl_name.fmt(ip), decl_index,
|
||||
});
|
||||
comp.work_queue.writeItemAssumeCapacity(.{ .analyze_decl = decl_index });
|
||||
}
|
||||
}
|
||||
|
||||
if (decl.getOwnedFunction(zcu) != null) {
|
||||
// TODO this logic is insufficient; namespaces we don't re-scan may still require
|
||||
// updated line numbers. Look into this!
|
||||
// TODO Look into detecting when this would be unnecessary by storing enough state
|
||||
// in `Decl` to notice that the line number did not change.
|
||||
comp.work_queue.writeItemAssumeCapacity(.{ .update_line_number = decl_index });
|
||||
}
|
||||
}
|
||||
|
||||
/// Cancel the creation of an anon decl and delete any references to it.
|
||||
/// If other decls depend on this decl, they must be aborted first.
|
||||
pub fn abortAnonDecl(mod: *Module, decl_index: Decl.Index) void {
|
||||
|
@ -5,6 +5,411 @@ tid: Id,
|
||||
|
||||
pub const Id = if (builtin.single_threaded) enum { main } else enum(usize) { main, _ };
|
||||
|
||||
pub fn astGenFile(
|
||||
pt: Zcu.PerThread,
|
||||
file: *Zcu.File,
|
||||
/// This parameter is provided separately from `file` because it is not
|
||||
/// safe to access `import_table` without a lock, and this index is needed
|
||||
/// in the call to `updateZirRefs`.
|
||||
file_index: Zcu.File.Index,
|
||||
path_digest: Cache.BinDigest,
|
||||
opt_root_decl: Zcu.Decl.OptionalIndex,
|
||||
) !void {
|
||||
assert(!file.mod.isBuiltin());
|
||||
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
const zcu = pt.zcu;
|
||||
const comp = zcu.comp;
|
||||
const gpa = zcu.gpa;
|
||||
|
||||
// In any case we need to examine the stat of the file to determine the course of action.
|
||||
var source_file = try file.mod.root.openFile(file.sub_file_path, .{});
|
||||
defer source_file.close();
|
||||
|
||||
const stat = try source_file.stat();
|
||||
|
||||
const want_local_cache = file.mod == zcu.main_mod;
|
||||
const hex_digest = Cache.binToHex(path_digest);
|
||||
const cache_directory = if (want_local_cache) zcu.local_zir_cache else zcu.global_zir_cache;
|
||||
const zir_dir = cache_directory.handle;
|
||||
|
||||
// Determine whether we need to reload the file from disk and redo parsing and AstGen.
|
||||
var lock: std.fs.File.Lock = switch (file.status) {
|
||||
.never_loaded, .retryable_failure => lock: {
|
||||
// First, load the cached ZIR code, if any.
|
||||
log.debug("AstGen checking cache: {s} (local={}, digest={s})", .{
|
||||
file.sub_file_path, want_local_cache, &hex_digest,
|
||||
});
|
||||
|
||||
break :lock .shared;
|
||||
},
|
||||
.parse_failure, .astgen_failure, .success_zir => lock: {
|
||||
const unchanged_metadata =
|
||||
stat.size == file.stat.size and
|
||||
stat.mtime == file.stat.mtime and
|
||||
stat.inode == file.stat.inode;
|
||||
|
||||
if (unchanged_metadata) {
|
||||
log.debug("unmodified metadata of file: {s}", .{file.sub_file_path});
|
||||
return;
|
||||
}
|
||||
|
||||
log.debug("metadata changed: {s}", .{file.sub_file_path});
|
||||
|
||||
break :lock .exclusive;
|
||||
},
|
||||
};
|
||||
|
||||
// We ask for a lock in order to coordinate with other zig processes.
|
||||
// If another process is already working on this file, we will get the cached
|
||||
// version. Likewise if we're working on AstGen and another process asks for
|
||||
// the cached file, they'll get it.
|
||||
const cache_file = while (true) {
|
||||
break zir_dir.createFile(&hex_digest, .{
|
||||
.read = true,
|
||||
.truncate = false,
|
||||
.lock = lock,
|
||||
}) catch |err| switch (err) {
|
||||
error.NotDir => unreachable, // no dir components
|
||||
error.InvalidUtf8 => unreachable, // it's a hex encoded name
|
||||
error.InvalidWtf8 => unreachable, // it's a hex encoded name
|
||||
error.BadPathName => unreachable, // it's a hex encoded name
|
||||
error.NameTooLong => unreachable, // it's a fixed size name
|
||||
error.PipeBusy => unreachable, // it's not a pipe
|
||||
error.WouldBlock => unreachable, // not asking for non-blocking I/O
|
||||
// There are no dir components, so you would think that this was
|
||||
// unreachable, however we have observed on macOS two processes racing
|
||||
// to do openat() with O_CREAT manifest in ENOENT.
|
||||
error.FileNotFound => continue,
|
||||
|
||||
else => |e| return e, // Retryable errors are handled at callsite.
|
||||
};
|
||||
};
|
||||
defer cache_file.close();
|
||||
|
||||
while (true) {
|
||||
update: {
|
||||
// First we read the header to determine the lengths of arrays.
|
||||
const header = cache_file.reader().readStruct(Zir.Header) catch |err| switch (err) {
|
||||
// This can happen if Zig bails out of this function between creating
|
||||
// the cached file and writing it.
|
||||
error.EndOfStream => break :update,
|
||||
else => |e| return e,
|
||||
};
|
||||
const unchanged_metadata =
|
||||
stat.size == header.stat_size and
|
||||
stat.mtime == header.stat_mtime and
|
||||
stat.inode == header.stat_inode;
|
||||
|
||||
if (!unchanged_metadata) {
|
||||
log.debug("AstGen cache stale: {s}", .{file.sub_file_path});
|
||||
break :update;
|
||||
}
|
||||
log.debug("AstGen cache hit: {s} instructions_len={d}", .{
|
||||
file.sub_file_path, header.instructions_len,
|
||||
});
|
||||
|
||||
file.zir = Zcu.loadZirCacheBody(gpa, header, cache_file) catch |err| switch (err) {
|
||||
error.UnexpectedFileSize => {
|
||||
log.warn("unexpected EOF reading cached ZIR for {s}", .{file.sub_file_path});
|
||||
break :update;
|
||||
},
|
||||
else => |e| return e,
|
||||
};
|
||||
file.zir_loaded = true;
|
||||
file.stat = .{
|
||||
.size = header.stat_size,
|
||||
.inode = header.stat_inode,
|
||||
.mtime = header.stat_mtime,
|
||||
};
|
||||
file.status = .success_zir;
|
||||
log.debug("AstGen cached success: {s}", .{file.sub_file_path});
|
||||
|
||||
// TODO don't report compile errors until Sema @importFile
|
||||
if (file.zir.hasCompileErrors()) {
|
||||
{
|
||||
comp.mutex.lock();
|
||||
defer comp.mutex.unlock();
|
||||
try zcu.failed_files.putNoClobber(gpa, file, null);
|
||||
}
|
||||
file.status = .astgen_failure;
|
||||
return error.AnalysisFail;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// If we already have the exclusive lock then it is our job to update.
|
||||
if (builtin.os.tag == .wasi or lock == .exclusive) break;
|
||||
// Otherwise, unlock to give someone a chance to get the exclusive lock
|
||||
// and then upgrade to an exclusive lock.
|
||||
cache_file.unlock();
|
||||
lock = .exclusive;
|
||||
try cache_file.lock(lock);
|
||||
}
|
||||
|
||||
// The cache is definitely stale so delete the contents to avoid an underwrite later.
|
||||
cache_file.setEndPos(0) catch |err| switch (err) {
|
||||
error.FileTooBig => unreachable, // 0 is not too big
|
||||
|
||||
else => |e| return e,
|
||||
};
|
||||
|
||||
pt.lockAndClearFileCompileError(file);
|
||||
|
||||
// If the previous ZIR does not have compile errors, keep it around
|
||||
// in case parsing or new ZIR fails. In case of successful ZIR update
|
||||
// at the end of this function we will free it.
|
||||
// We keep the previous ZIR loaded so that we can use it
|
||||
// for the update next time it does not have any compile errors. This avoids
|
||||
// needlessly tossing out semantic analysis work when an error is
|
||||
// temporarily introduced.
|
||||
if (file.zir_loaded and !file.zir.hasCompileErrors()) {
|
||||
assert(file.prev_zir == null);
|
||||
const prev_zir_ptr = try gpa.create(Zir);
|
||||
file.prev_zir = prev_zir_ptr;
|
||||
prev_zir_ptr.* = file.zir;
|
||||
file.zir = undefined;
|
||||
file.zir_loaded = false;
|
||||
}
|
||||
file.unload(gpa);
|
||||
|
||||
if (stat.size > std.math.maxInt(u32))
|
||||
return error.FileTooBig;
|
||||
|
||||
const source = try gpa.allocSentinel(u8, @as(usize, @intCast(stat.size)), 0);
|
||||
defer if (!file.source_loaded) gpa.free(source);
|
||||
const amt = try source_file.readAll(source);
|
||||
if (amt != stat.size)
|
||||
return error.UnexpectedEndOfFile;
|
||||
|
||||
file.stat = .{
|
||||
.size = stat.size,
|
||||
.inode = stat.inode,
|
||||
.mtime = stat.mtime,
|
||||
};
|
||||
file.source = source;
|
||||
file.source_loaded = true;
|
||||
|
||||
file.tree = try Ast.parse(gpa, source, .zig);
|
||||
file.tree_loaded = true;
|
||||
|
||||
// Any potential AST errors are converted to ZIR errors here.
|
||||
file.zir = try AstGen.generate(gpa, file.tree);
|
||||
file.zir_loaded = true;
|
||||
file.status = .success_zir;
|
||||
log.debug("AstGen fresh success: {s}", .{file.sub_file_path});
|
||||
|
||||
const safety_buffer = if (Zcu.data_has_safety_tag)
|
||||
try gpa.alloc([8]u8, file.zir.instructions.len)
|
||||
else
|
||||
undefined;
|
||||
defer if (Zcu.data_has_safety_tag) gpa.free(safety_buffer);
|
||||
const data_ptr = if (Zcu.data_has_safety_tag)
|
||||
if (file.zir.instructions.len == 0)
|
||||
@as([*]const u8, undefined)
|
||||
else
|
||||
@as([*]const u8, @ptrCast(safety_buffer.ptr))
|
||||
else
|
||||
@as([*]const u8, @ptrCast(file.zir.instructions.items(.data).ptr));
|
||||
if (Zcu.data_has_safety_tag) {
|
||||
// The `Data` union has a safety tag but in the file format we store it without.
|
||||
for (file.zir.instructions.items(.data), 0..) |*data, i| {
|
||||
const as_struct: *const Zcu.HackDataLayout = @ptrCast(data);
|
||||
safety_buffer[i] = as_struct.data;
|
||||
}
|
||||
}
|
||||
|
||||
const header: Zir.Header = .{
|
||||
.instructions_len = @as(u32, @intCast(file.zir.instructions.len)),
|
||||
.string_bytes_len = @as(u32, @intCast(file.zir.string_bytes.len)),
|
||||
.extra_len = @as(u32, @intCast(file.zir.extra.len)),
|
||||
|
||||
.stat_size = stat.size,
|
||||
.stat_inode = stat.inode,
|
||||
.stat_mtime = stat.mtime,
|
||||
};
|
||||
var iovecs = [_]std.posix.iovec_const{
|
||||
.{
|
||||
.base = @as([*]const u8, @ptrCast(&header)),
|
||||
.len = @sizeOf(Zir.Header),
|
||||
},
|
||||
.{
|
||||
.base = @as([*]const u8, @ptrCast(file.zir.instructions.items(.tag).ptr)),
|
||||
.len = file.zir.instructions.len,
|
||||
},
|
||||
.{
|
||||
.base = data_ptr,
|
||||
.len = file.zir.instructions.len * 8,
|
||||
},
|
||||
.{
|
||||
.base = file.zir.string_bytes.ptr,
|
||||
.len = file.zir.string_bytes.len,
|
||||
},
|
||||
.{
|
||||
.base = @as([*]const u8, @ptrCast(file.zir.extra.ptr)),
|
||||
.len = file.zir.extra.len * 4,
|
||||
},
|
||||
};
|
||||
cache_file.writevAll(&iovecs) catch |err| {
|
||||
log.warn("unable to write cached ZIR code for {}{s} to {}{s}: {s}", .{
|
||||
file.mod.root, file.sub_file_path, cache_directory, &hex_digest, @errorName(err),
|
||||
});
|
||||
};
|
||||
|
||||
if (file.zir.hasCompileErrors()) {
|
||||
{
|
||||
comp.mutex.lock();
|
||||
defer comp.mutex.unlock();
|
||||
try zcu.failed_files.putNoClobber(gpa, file, null);
|
||||
}
|
||||
file.status = .astgen_failure;
|
||||
return error.AnalysisFail;
|
||||
}
|
||||
|
||||
if (file.prev_zir) |prev_zir| {
|
||||
try pt.updateZirRefs(file, file_index, prev_zir.*);
|
||||
// No need to keep previous ZIR.
|
||||
prev_zir.deinit(gpa);
|
||||
gpa.destroy(prev_zir);
|
||||
file.prev_zir = null;
|
||||
}
|
||||
|
||||
if (opt_root_decl.unwrap()) |root_decl| {
|
||||
// The root of this file must be re-analyzed, since the file has changed.
|
||||
comp.mutex.lock();
|
||||
defer comp.mutex.unlock();
|
||||
|
||||
log.debug("outdated root Decl: {}", .{root_decl});
|
||||
try zcu.outdated_file_root.put(gpa, root_decl, {});
|
||||
}
|
||||
}
|
||||
|
||||
/// This is called from the AstGen thread pool, so must acquire
|
||||
/// the Compilation mutex when acting on shared state.
|
||||
fn updateZirRefs(pt: Zcu.PerThread, file: *Zcu.File, file_index: Zcu.File.Index, old_zir: Zir) !void {
|
||||
const zcu = pt.zcu;
|
||||
const gpa = zcu.gpa;
|
||||
const new_zir = file.zir;
|
||||
|
||||
var inst_map: std.AutoHashMapUnmanaged(Zir.Inst.Index, Zir.Inst.Index) = .{};
|
||||
defer inst_map.deinit(gpa);
|
||||
|
||||
try Zcu.mapOldZirToNew(gpa, old_zir, new_zir, &inst_map);
|
||||
|
||||
const old_tag = old_zir.instructions.items(.tag);
|
||||
const old_data = old_zir.instructions.items(.data);
|
||||
|
||||
// TODO: this should be done after all AstGen workers complete, to avoid
|
||||
// iterating over this full set for every updated file.
|
||||
for (zcu.intern_pool.tracked_insts.keys(), 0..) |*ti, idx_raw| {
|
||||
const ti_idx: InternPool.TrackedInst.Index = @enumFromInt(idx_raw);
|
||||
if (ti.file != file_index) continue;
|
||||
const old_inst = ti.inst;
|
||||
ti.inst = inst_map.get(ti.inst) orelse {
|
||||
// Tracking failed for this instruction. Invalidate associated `src_hash` deps.
|
||||
zcu.comp.mutex.lock();
|
||||
defer zcu.comp.mutex.unlock();
|
||||
log.debug("tracking failed for %{d}", .{old_inst});
|
||||
try zcu.markDependeeOutdated(.{ .src_hash = ti_idx });
|
||||
continue;
|
||||
};
|
||||
|
||||
if (old_zir.getAssociatedSrcHash(old_inst)) |old_hash| hash_changed: {
|
||||
if (new_zir.getAssociatedSrcHash(ti.inst)) |new_hash| {
|
||||
if (std.zig.srcHashEql(old_hash, new_hash)) {
|
||||
break :hash_changed;
|
||||
}
|
||||
log.debug("hash for (%{d} -> %{d}) changed: {} -> {}", .{
|
||||
old_inst,
|
||||
ti.inst,
|
||||
std.fmt.fmtSliceHexLower(&old_hash),
|
||||
std.fmt.fmtSliceHexLower(&new_hash),
|
||||
});
|
||||
}
|
||||
// The source hash associated with this instruction changed - invalidate relevant dependencies.
|
||||
zcu.comp.mutex.lock();
|
||||
defer zcu.comp.mutex.unlock();
|
||||
try zcu.markDependeeOutdated(.{ .src_hash = ti_idx });
|
||||
}
|
||||
|
||||
// If this is a `struct_decl` etc, we must invalidate any outdated namespace dependencies.
|
||||
const has_namespace = switch (old_tag[@intFromEnum(old_inst)]) {
|
||||
.extended => switch (old_data[@intFromEnum(old_inst)].extended.opcode) {
|
||||
.struct_decl, .union_decl, .opaque_decl, .enum_decl => true,
|
||||
else => false,
|
||||
},
|
||||
else => false,
|
||||
};
|
||||
if (!has_namespace) continue;
|
||||
|
||||
var old_names: std.AutoArrayHashMapUnmanaged(InternPool.NullTerminatedString, void) = .{};
|
||||
defer old_names.deinit(zcu.gpa);
|
||||
{
|
||||
var it = old_zir.declIterator(old_inst);
|
||||
while (it.next()) |decl_inst| {
|
||||
const decl_name = old_zir.getDeclaration(decl_inst)[0].name;
|
||||
switch (decl_name) {
|
||||
.@"comptime", .@"usingnamespace", .unnamed_test, .decltest => continue,
|
||||
_ => if (decl_name.isNamedTest(old_zir)) continue,
|
||||
}
|
||||
const name_zir = decl_name.toString(old_zir).?;
|
||||
const name_ip = try zcu.intern_pool.getOrPutString(
|
||||
zcu.gpa,
|
||||
pt.tid,
|
||||
old_zir.nullTerminatedString(name_zir),
|
||||
.no_embedded_nulls,
|
||||
);
|
||||
try old_names.put(zcu.gpa, name_ip, {});
|
||||
}
|
||||
}
|
||||
var any_change = false;
|
||||
{
|
||||
var it = new_zir.declIterator(ti.inst);
|
||||
while (it.next()) |decl_inst| {
|
||||
const decl_name = old_zir.getDeclaration(decl_inst)[0].name;
|
||||
switch (decl_name) {
|
||||
.@"comptime", .@"usingnamespace", .unnamed_test, .decltest => continue,
|
||||
_ => if (decl_name.isNamedTest(old_zir)) continue,
|
||||
}
|
||||
const name_zir = decl_name.toString(old_zir).?;
|
||||
const name_ip = try zcu.intern_pool.getOrPutString(
|
||||
zcu.gpa,
|
||||
pt.tid,
|
||||
old_zir.nullTerminatedString(name_zir),
|
||||
.no_embedded_nulls,
|
||||
);
|
||||
if (!old_names.swapRemove(name_ip)) continue;
|
||||
// Name added
|
||||
any_change = true;
|
||||
zcu.comp.mutex.lock();
|
||||
defer zcu.comp.mutex.unlock();
|
||||
try zcu.markDependeeOutdated(.{ .namespace_name = .{
|
||||
.namespace = ti_idx,
|
||||
.name = name_ip,
|
||||
} });
|
||||
}
|
||||
}
|
||||
// The only elements remaining in `old_names` now are any names which were removed.
|
||||
for (old_names.keys()) |name_ip| {
|
||||
any_change = true;
|
||||
zcu.comp.mutex.lock();
|
||||
defer zcu.comp.mutex.unlock();
|
||||
try zcu.markDependeeOutdated(.{ .namespace_name = .{
|
||||
.namespace = ti_idx,
|
||||
.name = name_ip,
|
||||
} });
|
||||
}
|
||||
|
||||
if (any_change) {
|
||||
zcu.comp.mutex.lock();
|
||||
defer zcu.comp.mutex.unlock();
|
||||
try zcu.markDependeeOutdated(.{ .namespace = ti_idx });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Like `ensureDeclAnalyzed`, but the Decl is a file's root Decl.
|
||||
pub fn ensureFileAnalyzed(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void {
|
||||
if (pt.zcu.fileRootDecl(file_index).unwrap()) |existing_root| {
|
||||
@ -91,7 +496,7 @@ pub fn ensureDeclAnalyzed(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) Zcu.Sem
|
||||
};
|
||||
}
|
||||
|
||||
const decl_prog_node = mod.sema_prog_node.start((try decl.fullyQualifiedName(mod)).toSlice(ip), 0);
|
||||
const decl_prog_node = mod.sema_prog_node.start((try decl.fullyQualifiedName(pt)).toSlice(ip), 0);
|
||||
defer decl_prog_node.end();
|
||||
|
||||
break :blk pt.semaDecl(decl_index) catch |err| switch (err) {
|
||||
@ -290,7 +695,7 @@ pub fn linkerUpdateFunc(pt: Zcu.PerThread, func_index: InternPool.Index, air: Ai
|
||||
defer liveness.deinit(gpa);
|
||||
|
||||
if (build_options.enable_debug_extensions and comp.verbose_air) {
|
||||
const fqn = try decl.fullyQualifiedName(zcu);
|
||||
const fqn = try decl.fullyQualifiedName(pt);
|
||||
std.debug.print("# Begin Function AIR: {}:\n", .{fqn.fmt(ip)});
|
||||
@import("../print_air.zig").dump(pt, air, liveness);
|
||||
std.debug.print("# End Function AIR: {}\n\n", .{fqn.fmt(ip)});
|
||||
@ -324,7 +729,7 @@ pub fn linkerUpdateFunc(pt: Zcu.PerThread, func_index: InternPool.Index, air: Ai
|
||||
};
|
||||
}
|
||||
|
||||
const codegen_prog_node = zcu.codegen_prog_node.start((try decl.fullyQualifiedName(zcu)).toSlice(ip), 0);
|
||||
const codegen_prog_node = zcu.codegen_prog_node.start((try decl.fullyQualifiedName(pt)).toSlice(ip), 0);
|
||||
defer codegen_prog_node.end();
|
||||
|
||||
if (!air.typesFullyResolved(zcu)) {
|
||||
@ -434,7 +839,7 @@ fn getFileRootStruct(
|
||||
decl.owns_tv = true;
|
||||
decl.analysis = .complete;
|
||||
|
||||
try zcu.scanNamespace(namespace_index, decls, decl);
|
||||
try pt.scanNamespace(namespace_index, decls, decl);
|
||||
try zcu.comp.work_queue.writeItem(.{ .resolve_type_fully = wip_ty.index });
|
||||
return wip_ty.finish(ip, decl_index, namespace_index.toOptional());
|
||||
}
|
||||
@ -502,7 +907,7 @@ fn semaFileUpdate(pt: Zcu.PerThread, file_index: Zcu.File.Index, type_outdated:
|
||||
const decls = file.zir.bodySlice(extra_index, decls_len);
|
||||
|
||||
if (!type_outdated) {
|
||||
try zcu.scanNamespace(decl.src_namespace, decls, decl);
|
||||
try pt.scanNamespace(decl.src_namespace, decls, decl);
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -539,7 +944,7 @@ fn semaFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void {
|
||||
zcu.setFileRootDecl(file_index, new_decl_index.toOptional());
|
||||
zcu.namespacePtr(new_namespace_index).decl_index = new_decl_index;
|
||||
|
||||
new_decl.name = try file.fullyQualifiedName(zcu);
|
||||
new_decl.name = try file.fullyQualifiedName(pt);
|
||||
new_decl.name_fully_qualified = true;
|
||||
new_decl.is_pub = true;
|
||||
new_decl.is_exported = false;
|
||||
@ -601,9 +1006,9 @@ fn semaDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !Zcu.SemaDeclResult {
|
||||
}
|
||||
|
||||
log.debug("semaDecl '{d}'", .{@intFromEnum(decl_index)});
|
||||
log.debug("decl name '{}'", .{(try decl.fullyQualifiedName(zcu)).fmt(ip)});
|
||||
log.debug("decl name '{}'", .{(try decl.fullyQualifiedName(pt)).fmt(ip)});
|
||||
defer blk: {
|
||||
log.debug("finish decl name '{}'", .{(decl.fullyQualifiedName(zcu) catch break :blk).fmt(ip)});
|
||||
log.debug("finish decl name '{}'", .{(decl.fullyQualifiedName(pt) catch break :blk).fmt(ip)});
|
||||
}
|
||||
|
||||
const old_has_tv = decl.has_tv;
|
||||
@ -631,7 +1036,7 @@ fn semaDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !Zcu.SemaDeclResult {
|
||||
const std_file_root_decl_index = zcu.fileRootDecl(std_file_imported.file_index);
|
||||
const std_decl = zcu.declPtr(std_file_root_decl_index.unwrap().?);
|
||||
const std_namespace = std_decl.getInnerNamespace(zcu).?;
|
||||
const builtin_str = try ip.getOrPutString(gpa, "builtin", .no_embedded_nulls);
|
||||
const builtin_str = try ip.getOrPutString(gpa, pt.tid, "builtin", .no_embedded_nulls);
|
||||
const builtin_decl = zcu.declPtr(std_namespace.decls.getKeyAdapted(builtin_str, Zcu.DeclAdapter{ .zcu = zcu }) orelse break :ip_index .none);
|
||||
const builtin_namespace = builtin_decl.getInnerNamespaceIndex(zcu).unwrap() orelse break :ip_index .none;
|
||||
if (decl.src_namespace != builtin_namespace) break :ip_index .none;
|
||||
@ -802,7 +1207,7 @@ fn semaDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !Zcu.SemaDeclResult {
|
||||
} else if (bytes.len == 0) {
|
||||
return sema.fail(&block_scope, section_src, "linksection cannot be empty", .{});
|
||||
}
|
||||
break :blk try ip.getOrPutStringOpt(gpa, bytes, .no_embedded_nulls);
|
||||
break :blk try ip.getOrPutStringOpt(gpa, pt.tid, bytes, .no_embedded_nulls);
|
||||
};
|
||||
decl.@"addrspace" = blk: {
|
||||
const addrspace_ctx: Sema.AddressSpaceContext = switch (ip.indexToKey(decl_val.toIntern())) {
|
||||
@ -996,7 +1401,7 @@ fn newEmbedFile(
|
||||
} });
|
||||
const array_val = try pt.intern(.{ .aggregate = .{
|
||||
.ty = array_ty,
|
||||
.storage = .{ .bytes = try ip.getOrPutTrailingString(gpa, bytes.len, .maybe_embedded_nulls) },
|
||||
.storage = .{ .bytes = try ip.getOrPutTrailingString(gpa, pt.tid, bytes.len, .maybe_embedded_nulls) },
|
||||
} });
|
||||
|
||||
const ptr_ty = (try pt.ptrType(.{
|
||||
@ -1018,7 +1423,7 @@ fn newEmbedFile(
|
||||
|
||||
result.* = new_file;
|
||||
new_file.* = .{
|
||||
.sub_file_path = try ip.getOrPutString(gpa, sub_file_path, .no_embedded_nulls),
|
||||
.sub_file_path = try ip.getOrPutString(gpa, pt.tid, sub_file_path, .no_embedded_nulls),
|
||||
.owner = pkg,
|
||||
.stat = stat,
|
||||
.val = ptr_val,
|
||||
@ -1027,6 +1432,271 @@ fn newEmbedFile(
|
||||
return ptr_val;
|
||||
}
|
||||
|
||||
pub fn scanNamespace(
|
||||
pt: Zcu.PerThread,
|
||||
namespace_index: Zcu.Namespace.Index,
|
||||
decls: []const Zir.Inst.Index,
|
||||
parent_decl: *Zcu.Decl,
|
||||
) Allocator.Error!void {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
const zcu = pt.zcu;
|
||||
const gpa = zcu.gpa;
|
||||
const namespace = zcu.namespacePtr(namespace_index);
|
||||
|
||||
// For incremental updates, `scanDecl` wants to look up existing decls by their ZIR index rather
|
||||
// than their name. We'll build an efficient mapping now, then discard the current `decls`.
|
||||
var existing_by_inst: std.AutoHashMapUnmanaged(InternPool.TrackedInst.Index, Zcu.Decl.Index) = .{};
|
||||
defer existing_by_inst.deinit(gpa);
|
||||
|
||||
try existing_by_inst.ensureTotalCapacity(gpa, @intCast(namespace.decls.count()));
|
||||
|
||||
for (namespace.decls.keys()) |decl_index| {
|
||||
const decl = zcu.declPtr(decl_index);
|
||||
existing_by_inst.putAssumeCapacityNoClobber(decl.zir_decl_index.unwrap().?, decl_index);
|
||||
}
|
||||
|
||||
var seen_decls: std.AutoHashMapUnmanaged(InternPool.NullTerminatedString, void) = .{};
|
||||
defer seen_decls.deinit(gpa);
|
||||
|
||||
try zcu.comp.work_queue.ensureUnusedCapacity(decls.len);
|
||||
|
||||
namespace.decls.clearRetainingCapacity();
|
||||
try namespace.decls.ensureTotalCapacity(gpa, decls.len);
|
||||
|
||||
namespace.usingnamespace_set.clearRetainingCapacity();
|
||||
|
||||
var scan_decl_iter: ScanDeclIter = .{
|
||||
.pt = pt,
|
||||
.namespace_index = namespace_index,
|
||||
.parent_decl = parent_decl,
|
||||
.seen_decls = &seen_decls,
|
||||
.existing_by_inst = &existing_by_inst,
|
||||
.pass = .named,
|
||||
};
|
||||
for (decls) |decl_inst| {
|
||||
try scan_decl_iter.scanDecl(decl_inst);
|
||||
}
|
||||
scan_decl_iter.pass = .unnamed;
|
||||
for (decls) |decl_inst| {
|
||||
try scan_decl_iter.scanDecl(decl_inst);
|
||||
}
|
||||
|
||||
if (seen_decls.count() != namespace.decls.count()) {
|
||||
// Do a pass over the namespace contents and remove any decls from the last update
|
||||
// which were removed in this one.
|
||||
var i: usize = 0;
|
||||
while (i < namespace.decls.count()) {
|
||||
const decl_index = namespace.decls.keys()[i];
|
||||
const decl = zcu.declPtr(decl_index);
|
||||
if (!seen_decls.contains(decl.name)) {
|
||||
// We must preserve namespace ordering for @typeInfo.
|
||||
namespace.decls.orderedRemoveAt(i);
|
||||
i -= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const ScanDeclIter = struct {
|
||||
pt: Zcu.PerThread,
|
||||
namespace_index: Zcu.Namespace.Index,
|
||||
parent_decl: *Zcu.Decl,
|
||||
seen_decls: *std.AutoHashMapUnmanaged(InternPool.NullTerminatedString, void),
|
||||
existing_by_inst: *const std.AutoHashMapUnmanaged(InternPool.TrackedInst.Index, Zcu.Decl.Index),
|
||||
/// Decl scanning is run in two passes, so that we can detect when a generated
|
||||
/// name would clash with an explicit name and use a different one.
|
||||
pass: enum { named, unnamed },
|
||||
usingnamespace_index: usize = 0,
|
||||
comptime_index: usize = 0,
|
||||
unnamed_test_index: usize = 0,
|
||||
|
||||
fn avoidNameConflict(iter: *ScanDeclIter, comptime fmt: []const u8, args: anytype) !InternPool.NullTerminatedString {
|
||||
const pt = iter.pt;
|
||||
const gpa = pt.zcu.gpa;
|
||||
const ip = &pt.zcu.intern_pool;
|
||||
var name = try ip.getOrPutStringFmt(gpa, pt.tid, fmt, args, .no_embedded_nulls);
|
||||
var gop = try iter.seen_decls.getOrPut(gpa, name);
|
||||
var next_suffix: u32 = 0;
|
||||
while (gop.found_existing) {
|
||||
name = try ip.getOrPutStringFmt(gpa, pt.tid, "{}_{d}", .{ name.fmt(ip), next_suffix }, .no_embedded_nulls);
|
||||
gop = try iter.seen_decls.getOrPut(gpa, name);
|
||||
next_suffix += 1;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
fn scanDecl(iter: *ScanDeclIter, decl_inst: Zir.Inst.Index) Allocator.Error!void {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
const pt = iter.pt;
|
||||
const zcu = pt.zcu;
|
||||
const namespace_index = iter.namespace_index;
|
||||
const namespace = zcu.namespacePtr(namespace_index);
|
||||
const gpa = zcu.gpa;
|
||||
const zir = namespace.fileScope(zcu).zir;
|
||||
const ip = &zcu.intern_pool;
|
||||
|
||||
const inst_data = zir.instructions.items(.data)[@intFromEnum(decl_inst)].declaration;
|
||||
const extra = zir.extraData(Zir.Inst.Declaration, inst_data.payload_index);
|
||||
const declaration = extra.data;
|
||||
|
||||
// Every Decl needs a name.
|
||||
const decl_name: InternPool.NullTerminatedString, const kind: Zcu.Decl.Kind, const is_named_test: bool = switch (declaration.name) {
|
||||
.@"comptime" => info: {
|
||||
if (iter.pass != .unnamed) return;
|
||||
const i = iter.comptime_index;
|
||||
iter.comptime_index += 1;
|
||||
break :info .{
|
||||
try iter.avoidNameConflict("comptime_{d}", .{i}),
|
||||
.@"comptime",
|
||||
false,
|
||||
};
|
||||
},
|
||||
.@"usingnamespace" => info: {
|
||||
// TODO: this isn't right! These should be considered unnamed. Name conflicts can happen here.
|
||||
// The problem is, we need to preserve the decl ordering for `@typeInfo`.
|
||||
// I'm not bothering to fix this now, since some upcoming changes will change this code significantly anyway.
|
||||
if (iter.pass != .named) return;
|
||||
const i = iter.usingnamespace_index;
|
||||
iter.usingnamespace_index += 1;
|
||||
break :info .{
|
||||
try iter.avoidNameConflict("usingnamespace_{d}", .{i}),
|
||||
.@"usingnamespace",
|
||||
false,
|
||||
};
|
||||
},
|
||||
.unnamed_test => info: {
|
||||
if (iter.pass != .unnamed) return;
|
||||
const i = iter.unnamed_test_index;
|
||||
iter.unnamed_test_index += 1;
|
||||
break :info .{
|
||||
try iter.avoidNameConflict("test_{d}", .{i}),
|
||||
.@"test",
|
||||
false,
|
||||
};
|
||||
},
|
||||
.decltest => info: {
|
||||
// We consider these to be unnamed since the decl name can be adjusted to avoid conflicts if necessary.
|
||||
if (iter.pass != .unnamed) return;
|
||||
assert(declaration.flags.has_doc_comment);
|
||||
const name = zir.nullTerminatedString(@enumFromInt(zir.extra[extra.end]));
|
||||
break :info .{
|
||||
try iter.avoidNameConflict("decltest.{s}", .{name}),
|
||||
.@"test",
|
||||
true,
|
||||
};
|
||||
},
|
||||
_ => if (declaration.name.isNamedTest(zir)) info: {
|
||||
// We consider these to be unnamed since the decl name can be adjusted to avoid conflicts if necessary.
|
||||
if (iter.pass != .unnamed) return;
|
||||
break :info .{
|
||||
try iter.avoidNameConflict("test.{s}", .{zir.nullTerminatedString(declaration.name.toString(zir).?)}),
|
||||
.@"test",
|
||||
true,
|
||||
};
|
||||
} else info: {
|
||||
if (iter.pass != .named) return;
|
||||
const name = try ip.getOrPutString(
|
||||
gpa,
|
||||
pt.tid,
|
||||
zir.nullTerminatedString(declaration.name.toString(zir).?),
|
||||
.no_embedded_nulls,
|
||||
);
|
||||
try iter.seen_decls.putNoClobber(gpa, name, {});
|
||||
break :info .{
|
||||
name,
|
||||
.named,
|
||||
false,
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
switch (kind) {
|
||||
.@"usingnamespace" => try namespace.usingnamespace_set.ensureUnusedCapacity(gpa, 1),
|
||||
.@"test" => try zcu.test_functions.ensureUnusedCapacity(gpa, 1),
|
||||
else => {},
|
||||
}
|
||||
|
||||
const parent_file_scope_index = iter.parent_decl.getFileScopeIndex(zcu);
|
||||
const tracked_inst = try ip.trackZir(gpa, parent_file_scope_index, decl_inst);
|
||||
|
||||
// We create a Decl for it regardless of analysis status.
|
||||
|
||||
const prev_exported, const decl_index = if (iter.existing_by_inst.get(tracked_inst)) |decl_index| decl_index: {
|
||||
// We need only update this existing Decl.
|
||||
const decl = zcu.declPtr(decl_index);
|
||||
const was_exported = decl.is_exported;
|
||||
assert(decl.kind == kind); // ZIR tracking should preserve this
|
||||
decl.name = decl_name;
|
||||
decl.is_pub = declaration.flags.is_pub;
|
||||
decl.is_exported = declaration.flags.is_export;
|
||||
break :decl_index .{ was_exported, decl_index };
|
||||
} else decl_index: {
|
||||
// Create and set up a new Decl.
|
||||
const new_decl_index = try zcu.allocateNewDecl(namespace_index);
|
||||
const new_decl = zcu.declPtr(new_decl_index);
|
||||
new_decl.kind = kind;
|
||||
new_decl.name = decl_name;
|
||||
new_decl.is_pub = declaration.flags.is_pub;
|
||||
new_decl.is_exported = declaration.flags.is_export;
|
||||
new_decl.zir_decl_index = tracked_inst.toOptional();
|
||||
break :decl_index .{ false, new_decl_index };
|
||||
};
|
||||
|
||||
const decl = zcu.declPtr(decl_index);
|
||||
|
||||
namespace.decls.putAssumeCapacityNoClobberContext(decl_index, {}, .{ .zcu = zcu });
|
||||
|
||||
const comp = zcu.comp;
|
||||
const decl_mod = namespace.fileScope(zcu).mod;
|
||||
const want_analysis = declaration.flags.is_export or switch (kind) {
|
||||
.anon => unreachable,
|
||||
.@"comptime" => true,
|
||||
.@"usingnamespace" => a: {
|
||||
namespace.usingnamespace_set.putAssumeCapacityNoClobber(decl_index, declaration.flags.is_pub);
|
||||
break :a true;
|
||||
},
|
||||
.named => false,
|
||||
.@"test" => a: {
|
||||
if (!comp.config.is_test) break :a false;
|
||||
if (decl_mod != zcu.main_mod) break :a false;
|
||||
if (is_named_test and comp.test_filters.len > 0) {
|
||||
const decl_fqn = try namespace.fullyQualifiedName(pt, decl_name);
|
||||
const decl_fqn_slice = decl_fqn.toSlice(ip);
|
||||
for (comp.test_filters) |test_filter| {
|
||||
if (std.mem.indexOf(u8, decl_fqn_slice, test_filter)) |_| break;
|
||||
} else break :a false;
|
||||
}
|
||||
zcu.test_functions.putAssumeCapacity(decl_index, {}); // may clobber on incremental update
|
||||
break :a true;
|
||||
},
|
||||
};
|
||||
|
||||
if (want_analysis) {
|
||||
// We will not queue analysis if the decl has been analyzed on a previous update and
|
||||
// `is_export` is unchanged. In this case, the incremental update mechanism will handle
|
||||
// re-analysis for us if necessary.
|
||||
if (prev_exported != declaration.flags.is_export or decl.analysis == .unreferenced) {
|
||||
log.debug("scanDecl queue analyze_decl file='{s}' decl_name='{}' decl_index={d}", .{
|
||||
namespace.fileScope(zcu).sub_file_path, decl_name.fmt(ip), decl_index,
|
||||
});
|
||||
comp.work_queue.writeItemAssumeCapacity(.{ .analyze_decl = decl_index });
|
||||
}
|
||||
}
|
||||
|
||||
if (decl.getOwnedFunction(zcu) != null) {
|
||||
// TODO this logic is insufficient; namespaces we don't re-scan may still require
|
||||
// updated line numbers. Look into this!
|
||||
// TODO Look into detecting when this would be unnecessary by storing enough state
|
||||
// in `Decl` to notice that the line number did not change.
|
||||
comp.work_queue.writeItemAssumeCapacity(.{ .update_line_number = decl_index });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: Allocator) Zcu.SemaError!Air {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
@ -1038,12 +1708,12 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All
|
||||
const decl_index = func.owner_decl;
|
||||
const decl = mod.declPtr(decl_index);
|
||||
|
||||
log.debug("func name '{}'", .{(try decl.fullyQualifiedName(mod)).fmt(ip)});
|
||||
log.debug("func name '{}'", .{(try decl.fullyQualifiedName(pt)).fmt(ip)});
|
||||
defer blk: {
|
||||
log.debug("finish func name '{}'", .{(decl.fullyQualifiedName(mod) catch break :blk).fmt(ip)});
|
||||
log.debug("finish func name '{}'", .{(decl.fullyQualifiedName(pt) catch break :blk).fmt(ip)});
|
||||
}
|
||||
|
||||
const decl_prog_node = mod.sema_prog_node.start((try decl.fullyQualifiedName(mod)).toSlice(ip), 0);
|
||||
const decl_prog_node = mod.sema_prog_node.start((try decl.fullyQualifiedName(pt)).toSlice(ip), 0);
|
||||
defer decl_prog_node.end();
|
||||
|
||||
mod.intern_pool.removeDependenciesForDepender(gpa, InternPool.AnalUnit.wrap(.{ .func = func_index }));
|
||||
@ -1273,6 +1943,19 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All
|
||||
};
|
||||
}
|
||||
|
||||
fn lockAndClearFileCompileError(pt: Zcu.PerThread, file: *Zcu.File) void {
|
||||
switch (file.status) {
|
||||
.success_zir, .retryable_failure => {},
|
||||
.never_loaded, .parse_failure, .astgen_failure => {
|
||||
pt.zcu.comp.mutex.lock();
|
||||
defer pt.zcu.comp.mutex.unlock();
|
||||
if (pt.zcu.failed_files.fetchSwapRemove(file)) |kv| {
|
||||
if (kv.value) |msg| msg.destroy(pt.zcu.gpa); // Delete previous error message.
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Called from `Compilation.update`, after everything is done, just before
|
||||
/// reporting compile errors. In this function we emit exported symbol collision
|
||||
/// errors and communicate exported symbols to the linker backend.
|
||||
@ -1397,7 +2080,7 @@ pub fn populateTestFunctions(
|
||||
const root_decl_index = zcu.fileRootDecl(builtin_file_index);
|
||||
const root_decl = zcu.declPtr(root_decl_index.unwrap().?);
|
||||
const builtin_namespace = zcu.namespacePtr(root_decl.src_namespace);
|
||||
const test_functions_str = try ip.getOrPutString(gpa, "test_functions", .no_embedded_nulls);
|
||||
const test_functions_str = try ip.getOrPutString(gpa, pt.tid, "test_functions", .no_embedded_nulls);
|
||||
const decl_index = builtin_namespace.decls.getKeyAdapted(
|
||||
test_functions_str,
|
||||
Zcu.DeclAdapter{ .zcu = zcu },
|
||||
@ -1424,7 +2107,7 @@ pub fn populateTestFunctions(
|
||||
|
||||
for (test_fn_vals, zcu.test_functions.keys()) |*test_fn_val, test_decl_index| {
|
||||
const test_decl = zcu.declPtr(test_decl_index);
|
||||
const test_decl_name = try test_decl.fullyQualifiedName(zcu);
|
||||
const test_decl_name = try test_decl.fullyQualifiedName(pt);
|
||||
const test_decl_name_len = test_decl_name.length(ip);
|
||||
const test_name_anon_decl: InternPool.Key.Ptr.BaseAddr.AnonDecl = n: {
|
||||
const test_name_ty = try pt.arrayType(.{
|
||||
@ -1530,7 +2213,7 @@ pub fn linkerUpdateDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !void {
|
||||
|
||||
const decl = zcu.declPtr(decl_index);
|
||||
|
||||
const codegen_prog_node = zcu.codegen_prog_node.start((try decl.fullyQualifiedName(zcu)).toSlice(&zcu.intern_pool), 0);
|
||||
const codegen_prog_node = zcu.codegen_prog_node.start((try decl.fullyQualifiedName(pt)).toSlice(&zcu.intern_pool), 0);
|
||||
defer codegen_prog_node.end();
|
||||
|
||||
if (comp.bin_file) |lf| {
|
||||
@ -2064,11 +2747,11 @@ pub fn getBuiltinDecl(pt: Zcu.PerThread, name: []const u8) Allocator.Error!Inter
|
||||
const std_file_imported = zcu.importPkg(zcu.std_mod) catch @panic("failed to import lib/std.zig");
|
||||
const std_file_root_decl = zcu.fileRootDecl(std_file_imported.file_index).unwrap().?;
|
||||
const std_namespace = zcu.declPtr(std_file_root_decl).getOwnedInnerNamespace(zcu).?;
|
||||
const builtin_str = try ip.getOrPutString(gpa, "builtin", .no_embedded_nulls);
|
||||
const builtin_str = try ip.getOrPutString(gpa, pt.tid, "builtin", .no_embedded_nulls);
|
||||
const builtin_decl = std_namespace.decls.getKeyAdapted(builtin_str, Zcu.DeclAdapter{ .zcu = zcu }) orelse @panic("lib/std.zig is corrupt and missing 'builtin'");
|
||||
pt.ensureDeclAnalyzed(builtin_decl) catch @panic("std.builtin is corrupt");
|
||||
const builtin_namespace = zcu.declPtr(builtin_decl).getInnerNamespace(zcu) orelse @panic("std.builtin is corrupt");
|
||||
const name_str = try ip.getOrPutString(gpa, name, .no_embedded_nulls);
|
||||
const name_str = try ip.getOrPutString(gpa, pt.tid, name, .no_embedded_nulls);
|
||||
return builtin_namespace.decls.getKeyAdapted(name_str, Zcu.DeclAdapter{ .zcu = zcu }) orelse @panic("lib/std/builtin.zig is corrupt");
|
||||
}
|
||||
|
||||
@ -2082,6 +2765,8 @@ pub fn getBuiltinType(pt: Zcu.PerThread, name: []const u8) Allocator.Error!Type
|
||||
const Air = @import("../Air.zig");
|
||||
const Allocator = std.mem.Allocator;
|
||||
const assert = std.debug.assert;
|
||||
const Ast = std.zig.Ast;
|
||||
const AstGen = std.zig.AstGen;
|
||||
const BigIntConst = std.math.big.int.Const;
|
||||
const BigIntMutable = std.math.big.int.Mutable;
|
||||
const build_options = @import("build_options");
|
||||
|
@ -2204,14 +2204,14 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
|
||||
const func_val = (try func.air.value(pl_op.operand, pt)) orelse break :blk null;
|
||||
|
||||
if (func_val.getFunction(mod)) |function| {
|
||||
_ = try func.bin_file.getOrCreateAtomForDecl(function.owner_decl);
|
||||
_ = try func.bin_file.getOrCreateAtomForDecl(pt, function.owner_decl);
|
||||
break :blk function.owner_decl;
|
||||
} else if (func_val.getExternFunc(mod)) |extern_func| {
|
||||
const ext_decl = mod.declPtr(extern_func.decl);
|
||||
const ext_info = mod.typeToFunc(ext_decl.typeOf(mod)).?;
|
||||
var func_type = try genFunctype(func.gpa, ext_info.cc, ext_info.param_types.get(ip), Type.fromInterned(ext_info.return_type), pt);
|
||||
defer func_type.deinit(func.gpa);
|
||||
const atom_index = try func.bin_file.getOrCreateAtomForDecl(extern_func.decl);
|
||||
const atom_index = try func.bin_file.getOrCreateAtomForDecl(pt, extern_func.decl);
|
||||
const atom = func.bin_file.getAtomPtr(atom_index);
|
||||
const type_index = try func.bin_file.storeDeclType(extern_func.decl, func_type);
|
||||
try func.bin_file.addOrUpdateImport(
|
||||
@ -2224,7 +2224,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
|
||||
} else switch (mod.intern_pool.indexToKey(func_val.ip_index)) {
|
||||
.ptr => |ptr| if (ptr.byte_offset == 0) switch (ptr.base_addr) {
|
||||
.decl => |decl| {
|
||||
_ = try func.bin_file.getOrCreateAtomForDecl(decl);
|
||||
_ = try func.bin_file.getOrCreateAtomForDecl(pt, decl);
|
||||
break :blk decl;
|
||||
},
|
||||
else => {},
|
||||
@ -3227,7 +3227,7 @@ fn lowerDeclRefValue(func: *CodeGen, decl_index: InternPool.DeclIndex, offset: u
|
||||
return WValue{ .imm32 = 0xaaaaaaaa };
|
||||
}
|
||||
|
||||
const atom_index = try func.bin_file.getOrCreateAtomForDecl(decl_index);
|
||||
const atom_index = try func.bin_file.getOrCreateAtomForDecl(pt, decl_index);
|
||||
const atom = func.bin_file.getAtom(atom_index);
|
||||
|
||||
const target_sym_index = @intFromEnum(atom.sym_index);
|
||||
@ -7284,7 +7284,7 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {
|
||||
defer arena_allocator.deinit();
|
||||
const arena = arena_allocator.allocator();
|
||||
|
||||
const fqn = try mod.declPtr(enum_decl_index).fullyQualifiedName(mod);
|
||||
const fqn = try mod.declPtr(enum_decl_index).fullyQualifiedName(pt);
|
||||
const func_name = try std.fmt.allocPrintZ(arena, "__zig_tag_name_{}", .{fqn.fmt(ip)});
|
||||
|
||||
// check if we already generated code for this.
|
||||
|
@ -756,7 +756,7 @@ fn lowerDeclRef(
|
||||
return Result.ok;
|
||||
}
|
||||
|
||||
const vaddr = try lf.getDeclVAddr(decl_index, .{
|
||||
const vaddr = try lf.getDeclVAddr(pt, decl_index, .{
|
||||
.parent_atom_index = reloc_info.parent_atom_index,
|
||||
.offset = code.items.len,
|
||||
.addend = @intCast(offset),
|
||||
|
@ -1744,7 +1744,7 @@ pub const Object = struct {
|
||||
if (export_indices.len != 0) {
|
||||
return updateExportedGlobal(self, zcu, global_index, export_indices);
|
||||
} else {
|
||||
const fqn = try self.builder.strtabString((try decl.fullyQualifiedName(zcu)).toSlice(ip));
|
||||
const fqn = try self.builder.strtabString((try decl.fullyQualifiedName(pt)).toSlice(ip));
|
||||
try global_index.rename(fqn, &self.builder);
|
||||
global_index.setLinkage(.internal, &self.builder);
|
||||
if (comp.config.dll_export_fns)
|
||||
@ -2520,7 +2520,7 @@ pub const Object = struct {
|
||||
const field_offset = ty.structFieldOffset(field_index, pt);
|
||||
|
||||
const field_name = struct_type.fieldName(ip, field_index).unwrap() orelse
|
||||
try ip.getOrPutStringFmt(gpa, "{d}", .{field_index}, .no_embedded_nulls);
|
||||
try ip.getOrPutStringFmt(gpa, pt.tid, "{d}", .{field_index}, .no_embedded_nulls);
|
||||
|
||||
fields.appendAssumeCapacity(try o.builder.debugMemberType(
|
||||
try o.builder.metadataString(field_name.toSlice(ip)),
|
||||
@ -2807,17 +2807,18 @@ pub const Object = struct {
|
||||
}
|
||||
|
||||
fn getStackTraceType(o: *Object) Allocator.Error!Type {
|
||||
const zcu = o.pt.zcu;
|
||||
const pt = o.pt;
|
||||
const zcu = pt.zcu;
|
||||
|
||||
const std_mod = zcu.std_mod;
|
||||
const std_file_imported = zcu.importPkg(std_mod) catch unreachable;
|
||||
|
||||
const builtin_str = try zcu.intern_pool.getOrPutString(zcu.gpa, "builtin", .no_embedded_nulls);
|
||||
const builtin_str = try zcu.intern_pool.getOrPutString(zcu.gpa, pt.tid, "builtin", .no_embedded_nulls);
|
||||
const std_file_root_decl = zcu.fileRootDecl(std_file_imported.file_index);
|
||||
const std_namespace = zcu.namespacePtr(zcu.declPtr(std_file_root_decl.unwrap().?).src_namespace);
|
||||
const builtin_decl = std_namespace.decls.getKeyAdapted(builtin_str, Zcu.DeclAdapter{ .zcu = zcu }).?;
|
||||
|
||||
const stack_trace_str = try zcu.intern_pool.getOrPutString(zcu.gpa, "StackTrace", .no_embedded_nulls);
|
||||
const stack_trace_str = try zcu.intern_pool.getOrPutString(zcu.gpa, pt.tid, "StackTrace", .no_embedded_nulls);
|
||||
// buffer is only used for int_type, `builtin` is a struct.
|
||||
const builtin_ty = zcu.declPtr(builtin_decl).val.toType();
|
||||
const builtin_namespace = zcu.namespacePtrUnwrap(builtin_ty.getNamespaceIndex(zcu)).?;
|
||||
@ -2865,7 +2866,7 @@ pub const Object = struct {
|
||||
try o.builder.strtabString((if (is_extern)
|
||||
decl.name
|
||||
else
|
||||
try decl.fullyQualifiedName(zcu)).toSlice(ip)),
|
||||
try decl.fullyQualifiedName(pt)).toSlice(ip)),
|
||||
toLlvmAddressSpace(decl.@"addrspace", target),
|
||||
);
|
||||
gop.value_ptr.* = function_index.ptrConst(&o.builder).global;
|
||||
@ -3074,7 +3075,8 @@ pub const Object = struct {
|
||||
if (gop.found_existing) return gop.value_ptr.ptr(&o.builder).kind.variable;
|
||||
errdefer assert(o.decl_map.remove(decl_index));
|
||||
|
||||
const zcu = o.pt.zcu;
|
||||
const pt = o.pt;
|
||||
const zcu = pt.zcu;
|
||||
const decl = zcu.declPtr(decl_index);
|
||||
const is_extern = decl.isExtern(zcu);
|
||||
|
||||
@ -3082,7 +3084,7 @@ pub const Object = struct {
|
||||
try o.builder.strtabString((if (is_extern)
|
||||
decl.name
|
||||
else
|
||||
try decl.fullyQualifiedName(zcu)).toSlice(&zcu.intern_pool)),
|
||||
try decl.fullyQualifiedName(pt)).toSlice(&zcu.intern_pool)),
|
||||
try o.lowerType(decl.typeOf(zcu)),
|
||||
toLlvmGlobalAddressSpace(decl.@"addrspace", zcu.getTarget()),
|
||||
);
|
||||
@ -3310,7 +3312,7 @@ pub const Object = struct {
|
||||
return int_ty;
|
||||
}
|
||||
|
||||
const fqn = try mod.declPtr(struct_type.decl.unwrap().?).fullyQualifiedName(mod);
|
||||
const fqn = try mod.declPtr(struct_type.decl.unwrap().?).fullyQualifiedName(pt);
|
||||
|
||||
var llvm_field_types = std.ArrayListUnmanaged(Builder.Type){};
|
||||
defer llvm_field_types.deinit(o.gpa);
|
||||
@ -3464,7 +3466,7 @@ pub const Object = struct {
|
||||
return enum_tag_ty;
|
||||
}
|
||||
|
||||
const fqn = try mod.declPtr(union_obj.decl).fullyQualifiedName(mod);
|
||||
const fqn = try mod.declPtr(union_obj.decl).fullyQualifiedName(pt);
|
||||
|
||||
const aligned_field_ty = Type.fromInterned(union_obj.field_types.get(ip)[layout.most_aligned_field]);
|
||||
const aligned_field_llvm_ty = try o.lowerType(aligned_field_ty);
|
||||
@ -3525,7 +3527,7 @@ pub const Object = struct {
|
||||
const gop = try o.type_map.getOrPut(o.gpa, t.toIntern());
|
||||
if (!gop.found_existing) {
|
||||
const decl = mod.declPtr(ip.loadOpaqueType(t.toIntern()).decl);
|
||||
const fqn = try decl.fullyQualifiedName(mod);
|
||||
const fqn = try decl.fullyQualifiedName(pt);
|
||||
gop.value_ptr.* = try o.builder.opaqueType(try o.builder.string(fqn.toSlice(ip)));
|
||||
}
|
||||
return gop.value_ptr.*;
|
||||
@ -4585,7 +4587,7 @@ pub const Object = struct {
|
||||
|
||||
const usize_ty = try o.lowerType(Type.usize);
|
||||
const ret_ty = try o.lowerType(Type.slice_const_u8_sentinel_0);
|
||||
const fqn = try zcu.declPtr(enum_type.decl).fullyQualifiedName(zcu);
|
||||
const fqn = try zcu.declPtr(enum_type.decl).fullyQualifiedName(pt);
|
||||
const target = zcu.root_mod.resolved_target.result;
|
||||
const function_index = try o.builder.addFunction(
|
||||
try o.builder.fnType(ret_ty, &.{try o.lowerType(Type.fromInterned(enum_type.tag_ty))}, .normal),
|
||||
@ -5173,7 +5175,7 @@ pub const FuncGen = struct {
|
||||
const line_number = decl.navSrcLine(zcu) + 1;
|
||||
self.inlined = self.wip.debug_location;
|
||||
|
||||
const fqn = try decl.fullyQualifiedName(zcu);
|
||||
const fqn = try decl.fullyQualifiedName(pt);
|
||||
|
||||
const fn_ty = try pt.funcType(.{
|
||||
.param_types = &.{},
|
||||
@ -9707,7 +9709,7 @@ pub const FuncGen = struct {
|
||||
if (gop.found_existing) return gop.value_ptr.*;
|
||||
errdefer assert(o.named_enum_map.remove(enum_type.decl));
|
||||
|
||||
const fqn = try zcu.declPtr(enum_type.decl).fullyQualifiedName(zcu);
|
||||
const fqn = try zcu.declPtr(enum_type.decl).fullyQualifiedName(pt);
|
||||
const target = zcu.root_mod.resolved_target.result;
|
||||
const function_index = try o.builder.addFunction(
|
||||
try o.builder.fnType(.i1, &.{try o.lowerType(Type.fromInterned(enum_type.tag_ty))}, .normal),
|
||||
|
@ -1753,7 +1753,7 @@ const DeclGen = struct {
|
||||
}
|
||||
|
||||
const field_name = struct_type.fieldName(ip, field_index).unwrap() orelse
|
||||
try ip.getOrPutStringFmt(mod.gpa, "{d}", .{field_index}, .no_embedded_nulls);
|
||||
try ip.getOrPutStringFmt(mod.gpa, pt.tid, "{d}", .{field_index}, .no_embedded_nulls);
|
||||
try member_types.append(try self.resolveType(field_ty, .indirect));
|
||||
try member_names.append(field_name.toSlice(ip));
|
||||
}
|
||||
@ -3012,7 +3012,7 @@ const DeclGen = struct {
|
||||
// Append the actual code into the functions section.
|
||||
try self.spv.addFunction(spv_decl_index, self.func);
|
||||
|
||||
const fqn = try decl.fullyQualifiedName(self.pt.zcu);
|
||||
const fqn = try decl.fullyQualifiedName(self.pt);
|
||||
try self.spv.debugName(result_id, fqn.toSlice(ip));
|
||||
|
||||
// Temporarily generate a test kernel declaration if this is a test function.
|
||||
@ -3041,7 +3041,7 @@ const DeclGen = struct {
|
||||
.storage_class = final_storage_class,
|
||||
});
|
||||
|
||||
const fqn = try decl.fullyQualifiedName(self.pt.zcu);
|
||||
const fqn = try decl.fullyQualifiedName(self.pt);
|
||||
try self.spv.debugName(result_id, fqn.toSlice(ip));
|
||||
try self.spv.declareDeclDeps(spv_decl_index, &.{});
|
||||
},
|
||||
@ -3086,7 +3086,7 @@ const DeclGen = struct {
|
||||
try self.func.body.emit(self.spv.gpa, .OpFunctionEnd, {});
|
||||
try self.spv.addFunction(spv_decl_index, self.func);
|
||||
|
||||
const fqn = try decl.fullyQualifiedName(self.pt.zcu);
|
||||
const fqn = try decl.fullyQualifiedName(self.pt);
|
||||
try self.spv.debugNameFmt(initializer_id, "initializer of {}", .{fqn.fmt(ip)});
|
||||
|
||||
try self.spv.sections.types_globals_constants.emit(self.spv.gpa, .OpExtInst, .{
|
||||
|
10
src/link.zig
10
src/link.zig
@ -424,14 +424,14 @@ pub const File = struct {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn updateDeclLineNumber(base: *File, module: *Zcu, decl_index: InternPool.DeclIndex) UpdateDeclError!void {
|
||||
const decl = module.declPtr(decl_index);
|
||||
pub fn updateDeclLineNumber(base: *File, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) UpdateDeclError!void {
|
||||
const decl = pt.zcu.declPtr(decl_index);
|
||||
assert(decl.has_tv);
|
||||
switch (base.tag) {
|
||||
.spirv, .nvptx => {},
|
||||
inline else => |tag| {
|
||||
if (tag != .c and build_options.only_c) unreachable;
|
||||
return @as(*tag.Type(), @fieldParentPtr("base", base)).updateDeclLineNumber(module, decl_index);
|
||||
return @as(*tag.Type(), @fieldParentPtr("base", base)).updateDeclLineNumber(pt, decl_index);
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -626,14 +626,14 @@ pub const File = struct {
|
||||
/// `Decl`'s address was not yet resolved, or the containing atom gets moved in virtual memory.
|
||||
/// May be called before or after updateFunc/updateDecl therefore it is up to the linker to allocate
|
||||
/// the block/atom.
|
||||
pub fn getDeclVAddr(base: *File, decl_index: InternPool.DeclIndex, reloc_info: RelocInfo) !u64 {
|
||||
pub fn getDeclVAddr(base: *File, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex, reloc_info: RelocInfo) !u64 {
|
||||
if (build_options.only_c) @compileError("unreachable");
|
||||
switch (base.tag) {
|
||||
.c => unreachable,
|
||||
.spirv => unreachable,
|
||||
.nvptx => unreachable,
|
||||
inline else => |tag| {
|
||||
return @as(*tag.Type(), @fieldParentPtr("base", base)).getDeclVAddr(decl_index, reloc_info);
|
||||
return @as(*tag.Type(), @fieldParentPtr("base", base)).getDeclVAddr(pt, decl_index, reloc_info);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -383,11 +383,11 @@ pub fn updateDecl(self: *C, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex)
|
||||
gop.value_ptr.fwd_decl = try self.addString(object.dg.fwd_decl.items);
|
||||
}
|
||||
|
||||
pub fn updateDeclLineNumber(self: *C, zcu: *Zcu, decl_index: InternPool.DeclIndex) !void {
|
||||
pub fn updateDeclLineNumber(self: *C, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !void {
|
||||
// The C backend does not have the ability to fix line numbers without re-generating
|
||||
// the entire Decl.
|
||||
_ = self;
|
||||
_ = zcu;
|
||||
_ = pt;
|
||||
_ = decl_index;
|
||||
}
|
||||
|
||||
|
@ -1176,7 +1176,7 @@ pub fn lowerUnnamedConst(self: *Coff, pt: Zcu.PerThread, val: Value, decl_index:
|
||||
gop.value_ptr.* = .{};
|
||||
}
|
||||
const unnamed_consts = gop.value_ptr;
|
||||
const decl_name = try decl.fullyQualifiedName(mod);
|
||||
const decl_name = try decl.fullyQualifiedName(pt);
|
||||
const index = unnamed_consts.items.len;
|
||||
const sym_name = try std.fmt.allocPrint(gpa, "__unnamed_{}_{d}", .{ decl_name.fmt(&mod.intern_pool), index });
|
||||
defer gpa.free(sym_name);
|
||||
@ -1427,7 +1427,7 @@ fn updateDeclCode(self: *Coff, pt: Zcu.PerThread, decl_index: InternPool.DeclInd
|
||||
const mod = pt.zcu;
|
||||
const decl = mod.declPtr(decl_index);
|
||||
|
||||
const decl_name = try decl.fullyQualifiedName(mod);
|
||||
const decl_name = try decl.fullyQualifiedName(pt);
|
||||
|
||||
log.debug("updateDeclCode {}{*}", .{ decl_name.fmt(&mod.intern_pool), decl });
|
||||
const required_alignment: u32 = @intCast(decl.getAlignment(pt).toByteUnits() orelse 0);
|
||||
@ -1855,7 +1855,7 @@ pub fn flushModule(self: *Coff, arena: Allocator, tid: Zcu.PerThread.Id, prog_no
|
||||
assert(!self.imports_count_dirty);
|
||||
}
|
||||
|
||||
pub fn getDeclVAddr(self: *Coff, decl_index: InternPool.DeclIndex, reloc_info: link.File.RelocInfo) !u64 {
|
||||
pub fn getDeclVAddr(self: *Coff, _: Zcu.PerThread, decl_index: InternPool.DeclIndex, reloc_info: link.File.RelocInfo) !u64 {
|
||||
assert(self.llvm_object == null);
|
||||
|
||||
const this_atom_index = try self.getOrCreateAtomForDecl(decl_index);
|
||||
@ -1972,9 +1972,9 @@ pub fn getGlobalSymbol(self: *Coff, name: []const u8, lib_name_name: ?[]const u8
|
||||
return global_index;
|
||||
}
|
||||
|
||||
pub fn updateDeclLineNumber(self: *Coff, module: *Module, decl_index: InternPool.DeclIndex) !void {
|
||||
pub fn updateDeclLineNumber(self: *Coff, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !void {
|
||||
_ = self;
|
||||
_ = module;
|
||||
_ = pt;
|
||||
_ = decl_index;
|
||||
log.debug("TODO implement updateDeclLineNumber", .{});
|
||||
}
|
||||
|
@ -1082,7 +1082,7 @@ pub fn initDeclState(self: *Dwarf, pt: Zcu.PerThread, decl_index: InternPool.Dec
|
||||
defer tracy.end();
|
||||
|
||||
const decl = pt.zcu.declPtr(decl_index);
|
||||
const decl_linkage_name = try decl.fullyQualifiedName(pt.zcu);
|
||||
const decl_linkage_name = try decl.fullyQualifiedName(pt);
|
||||
|
||||
log.debug("initDeclState {}{*}", .{ decl_linkage_name.fmt(&pt.zcu.intern_pool), decl });
|
||||
|
||||
|
@ -543,7 +543,7 @@ pub fn deinit(self: *Elf) void {
|
||||
self.comdat_group_sections.deinit(gpa);
|
||||
}
|
||||
|
||||
pub fn getDeclVAddr(self: *Elf, decl_index: InternPool.DeclIndex, reloc_info: link.File.RelocInfo) !u64 {
|
||||
pub fn getDeclVAddr(self: *Elf, _: Zcu.PerThread, decl_index: InternPool.DeclIndex, reloc_info: link.File.RelocInfo) !u64 {
|
||||
assert(self.llvm_object == null);
|
||||
return self.zigObjectPtr().?.getDeclVAddr(self, decl_index, reloc_info);
|
||||
}
|
||||
@ -3021,9 +3021,9 @@ pub fn updateExports(
|
||||
return self.zigObjectPtr().?.updateExports(self, pt, exported, export_indices);
|
||||
}
|
||||
|
||||
pub fn updateDeclLineNumber(self: *Elf, mod: *Module, decl_index: InternPool.DeclIndex) !void {
|
||||
pub fn updateDeclLineNumber(self: *Elf, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !void {
|
||||
if (self.llvm_object) |_| return;
|
||||
return self.zigObjectPtr().?.updateDeclLineNumber(mod, decl_index);
|
||||
return self.zigObjectPtr().?.updateDeclLineNumber(pt, decl_index);
|
||||
}
|
||||
|
||||
pub fn deleteExport(
|
||||
|
@ -908,7 +908,7 @@ fn updateDeclCode(
|
||||
const gpa = elf_file.base.comp.gpa;
|
||||
const mod = pt.zcu;
|
||||
const decl = mod.declPtr(decl_index);
|
||||
const decl_name = try decl.fullyQualifiedName(mod);
|
||||
const decl_name = try decl.fullyQualifiedName(pt);
|
||||
|
||||
log.debug("updateDeclCode {}{*}", .{ decl_name.fmt(&mod.intern_pool), decl });
|
||||
|
||||
@ -1009,7 +1009,7 @@ fn updateTlv(
|
||||
const mod = pt.zcu;
|
||||
const gpa = mod.gpa;
|
||||
const decl = mod.declPtr(decl_index);
|
||||
const decl_name = try decl.fullyQualifiedName(mod);
|
||||
const decl_name = try decl.fullyQualifiedName(pt);
|
||||
|
||||
log.debug("updateTlv {} ({*})", .{ decl_name.fmt(&mod.intern_pool), decl });
|
||||
|
||||
@ -1286,7 +1286,7 @@ pub fn lowerUnnamedConst(
|
||||
}
|
||||
const unnamed_consts = gop.value_ptr;
|
||||
const decl = mod.declPtr(decl_index);
|
||||
const decl_name = try decl.fullyQualifiedName(mod);
|
||||
const decl_name = try decl.fullyQualifiedName(pt);
|
||||
const index = unnamed_consts.items.len;
|
||||
const name = try std.fmt.allocPrint(gpa, "__unnamed_{}_{d}", .{ decl_name.fmt(&mod.intern_pool), index });
|
||||
defer gpa.free(name);
|
||||
@ -1466,19 +1466,19 @@ pub fn updateExports(
|
||||
/// Must be called only after a successful call to `updateDecl`.
|
||||
pub fn updateDeclLineNumber(
|
||||
self: *ZigObject,
|
||||
mod: *Module,
|
||||
pt: Zcu.PerThread,
|
||||
decl_index: InternPool.DeclIndex,
|
||||
) !void {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
const decl = mod.declPtr(decl_index);
|
||||
const decl_name = try decl.fullyQualifiedName(mod);
|
||||
const decl = pt.zcu.declPtr(decl_index);
|
||||
const decl_name = try decl.fullyQualifiedName(pt);
|
||||
|
||||
log.debug("updateDeclLineNumber {}{*}", .{ decl_name.fmt(&mod.intern_pool), decl });
|
||||
log.debug("updateDeclLineNumber {}{*}", .{ decl_name.fmt(&pt.zcu.intern_pool), decl });
|
||||
|
||||
if (self.dwarf) |*dw| {
|
||||
try dw.updateDeclLineNumber(mod, decl_index);
|
||||
try dw.updateDeclLineNumber(pt.zcu, decl_index);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3198,9 +3198,9 @@ pub fn updateDecl(self: *MachO, pt: Zcu.PerThread, decl_index: InternPool.DeclIn
|
||||
return self.getZigObject().?.updateDecl(self, pt, decl_index);
|
||||
}
|
||||
|
||||
pub fn updateDeclLineNumber(self: *MachO, module: *Module, decl_index: InternPool.DeclIndex) !void {
|
||||
pub fn updateDeclLineNumber(self: *MachO, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !void {
|
||||
if (self.llvm_object) |_| return;
|
||||
return self.getZigObject().?.updateDeclLineNumber(module, decl_index);
|
||||
return self.getZigObject().?.updateDeclLineNumber(pt, decl_index);
|
||||
}
|
||||
|
||||
pub fn updateExports(
|
||||
@ -3230,7 +3230,7 @@ pub fn freeDecl(self: *MachO, decl_index: InternPool.DeclIndex) void {
|
||||
return self.getZigObject().?.freeDecl(decl_index);
|
||||
}
|
||||
|
||||
pub fn getDeclVAddr(self: *MachO, decl_index: InternPool.DeclIndex, reloc_info: link.File.RelocInfo) !u64 {
|
||||
pub fn getDeclVAddr(self: *MachO, _: Zcu.PerThread, decl_index: InternPool.DeclIndex, reloc_info: link.File.RelocInfo) !u64 {
|
||||
assert(self.llvm_object == null);
|
||||
return self.getZigObject().?.getDeclVAddr(self, decl_index, reloc_info);
|
||||
}
|
||||
|
@ -810,7 +810,7 @@ fn updateDeclCode(
|
||||
const gpa = macho_file.base.comp.gpa;
|
||||
const mod = pt.zcu;
|
||||
const decl = mod.declPtr(decl_index);
|
||||
const decl_name = try decl.fullyQualifiedName(mod);
|
||||
const decl_name = try decl.fullyQualifiedName(pt);
|
||||
|
||||
log.debug("updateDeclCode {}{*}", .{ decl_name.fmt(&mod.intern_pool), decl });
|
||||
|
||||
@ -893,13 +893,12 @@ fn updateTlv(
|
||||
sect_index: u8,
|
||||
code: []const u8,
|
||||
) !void {
|
||||
const mod = pt.zcu;
|
||||
const decl = mod.declPtr(decl_index);
|
||||
const decl_name = try decl.fullyQualifiedName(mod);
|
||||
const decl = pt.zcu.declPtr(decl_index);
|
||||
const decl_name = try decl.fullyQualifiedName(pt);
|
||||
|
||||
log.debug("updateTlv {} ({*})", .{ decl_name.fmt(&mod.intern_pool), decl });
|
||||
log.debug("updateTlv {} ({*})", .{ decl_name.fmt(&pt.zcu.intern_pool), decl });
|
||||
|
||||
const decl_name_slice = decl_name.toSlice(&mod.intern_pool);
|
||||
const decl_name_slice = decl_name.toSlice(&pt.zcu.intern_pool);
|
||||
const required_alignment = decl.getAlignment(pt);
|
||||
|
||||
// 1. Lower TLV initializer
|
||||
@ -1100,7 +1099,7 @@ pub fn lowerUnnamedConst(
|
||||
}
|
||||
const unnamed_consts = gop.value_ptr;
|
||||
const decl = mod.declPtr(decl_index);
|
||||
const decl_name = try decl.fullyQualifiedName(mod);
|
||||
const decl_name = try decl.fullyQualifiedName(pt);
|
||||
const index = unnamed_consts.items.len;
|
||||
const name = try std.fmt.allocPrint(gpa, "__unnamed_{}_{d}", .{ decl_name.fmt(&mod.intern_pool), index });
|
||||
defer gpa.free(name);
|
||||
@ -1363,9 +1362,9 @@ fn updateLazySymbol(
|
||||
}
|
||||
|
||||
/// Must be called only after a successful call to `updateDecl`.
|
||||
pub fn updateDeclLineNumber(self: *ZigObject, mod: *Module, decl_index: InternPool.DeclIndex) !void {
|
||||
pub fn updateDeclLineNumber(self: *ZigObject, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !void {
|
||||
if (self.dwarf) |*dw| {
|
||||
try dw.updateDeclLineNumber(mod, decl_index);
|
||||
try dw.updateDeclLineNumber(pt.zcu, decl_index);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -483,7 +483,7 @@ pub fn lowerUnnamedConst(self: *Plan9, pt: Zcu.PerThread, val: Value, decl_index
|
||||
}
|
||||
const unnamed_consts = gop.value_ptr;
|
||||
|
||||
const decl_name = try decl.fullyQualifiedName(mod);
|
||||
const decl_name = try decl.fullyQualifiedName(pt);
|
||||
|
||||
const index = unnamed_consts.items.len;
|
||||
// name is freed when the unnamed const is freed
|
||||
@ -1496,22 +1496,22 @@ pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void {
|
||||
}
|
||||
|
||||
/// Must be called only after a successful call to `updateDecl`.
|
||||
pub fn updateDeclLineNumber(self: *Plan9, mod: *Zcu, decl_index: InternPool.DeclIndex) !void {
|
||||
pub fn updateDeclLineNumber(self: *Plan9, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !void {
|
||||
_ = self;
|
||||
_ = mod;
|
||||
_ = pt;
|
||||
_ = decl_index;
|
||||
}
|
||||
|
||||
pub fn getDeclVAddr(
|
||||
self: *Plan9,
|
||||
pt: Zcu.PerThread,
|
||||
decl_index: InternPool.DeclIndex,
|
||||
reloc_info: link.File.RelocInfo,
|
||||
) !u64 {
|
||||
const mod = self.base.comp.module.?;
|
||||
const ip = &mod.intern_pool;
|
||||
const decl = mod.declPtr(decl_index);
|
||||
const ip = &pt.zcu.intern_pool;
|
||||
const decl = pt.zcu.declPtr(decl_index);
|
||||
log.debug("getDeclVAddr for {}", .{decl.name.fmt(ip)});
|
||||
if (decl.isExtern(mod)) {
|
||||
if (decl.isExtern(pt.zcu)) {
|
||||
if (decl.name.eqlSlice("etext", ip)) {
|
||||
try self.addReloc(reloc_info.parent_atom_index, .{
|
||||
.target = undefined,
|
||||
|
@ -1457,9 +1457,9 @@ pub fn updateDecl(wasm: *Wasm, pt: Zcu.PerThread, decl_index: InternPool.DeclInd
|
||||
try wasm.zigObjectPtr().?.updateDecl(wasm, pt, decl_index);
|
||||
}
|
||||
|
||||
pub fn updateDeclLineNumber(wasm: *Wasm, mod: *Zcu, decl_index: InternPool.DeclIndex) !void {
|
||||
pub fn updateDeclLineNumber(wasm: *Wasm, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !void {
|
||||
if (wasm.llvm_object) |_| return;
|
||||
try wasm.zigObjectPtr().?.updateDeclLineNumber(mod, decl_index);
|
||||
try wasm.zigObjectPtr().?.updateDeclLineNumber(pt, decl_index);
|
||||
}
|
||||
|
||||
/// From a given symbol location, returns its `wasm.GlobalType`.
|
||||
@ -1521,10 +1521,11 @@ pub fn getGlobalSymbol(wasm: *Wasm, name: []const u8, lib_name: ?[]const u8) !Sy
|
||||
/// Returns the given pointer address
|
||||
pub fn getDeclVAddr(
|
||||
wasm: *Wasm,
|
||||
pt: Zcu.PerThread,
|
||||
decl_index: InternPool.DeclIndex,
|
||||
reloc_info: link.File.RelocInfo,
|
||||
) !u64 {
|
||||
return wasm.zigObjectPtr().?.getDeclVAddr(wasm, decl_index, reloc_info);
|
||||
return wasm.zigObjectPtr().?.getDeclVAddr(wasm, pt, decl_index, reloc_info);
|
||||
}
|
||||
|
||||
pub fn lowerAnonDecl(
|
||||
@ -4016,8 +4017,8 @@ pub fn getErrorTableSymbol(wasm_file: *Wasm, pt: Zcu.PerThread) !u32 {
|
||||
/// For a given `InternPool.DeclIndex` returns its corresponding `Atom.Index`.
|
||||
/// When the index was not found, a new `Atom` will be created, and its index will be returned.
|
||||
/// The newly created Atom is empty with default fields as specified by `Atom.empty`.
|
||||
pub fn getOrCreateAtomForDecl(wasm_file: *Wasm, decl_index: InternPool.DeclIndex) !Atom.Index {
|
||||
return wasm_file.zigObjectPtr().?.getOrCreateAtomForDecl(wasm_file, decl_index);
|
||||
pub fn getOrCreateAtomForDecl(wasm_file: *Wasm, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !Atom.Index {
|
||||
return wasm_file.zigObjectPtr().?.getOrCreateAtomForDecl(wasm_file, pt, decl_index);
|
||||
}
|
||||
|
||||
/// Verifies all resolved symbols and checks whether itself needs to be marked alive,
|
||||
|
@ -253,7 +253,7 @@ pub fn updateDecl(
|
||||
}
|
||||
|
||||
const gpa = wasm_file.base.comp.gpa;
|
||||
const atom_index = try zig_object.getOrCreateAtomForDecl(wasm_file, decl_index);
|
||||
const atom_index = try zig_object.getOrCreateAtomForDecl(wasm_file, pt, decl_index);
|
||||
const atom = wasm_file.getAtomPtr(atom_index);
|
||||
atom.clear();
|
||||
|
||||
@ -302,7 +302,7 @@ pub fn updateFunc(
|
||||
const func = pt.zcu.funcInfo(func_index);
|
||||
const decl_index = func.owner_decl;
|
||||
const decl = pt.zcu.declPtr(decl_index);
|
||||
const atom_index = try zig_object.getOrCreateAtomForDecl(wasm_file, decl_index);
|
||||
const atom_index = try zig_object.getOrCreateAtomForDecl(wasm_file, pt, decl_index);
|
||||
const atom = wasm_file.getAtomPtr(atom_index);
|
||||
atom.clear();
|
||||
|
||||
@ -346,7 +346,7 @@ fn finishUpdateDecl(
|
||||
const atom_index = decl_info.atom;
|
||||
const atom = wasm_file.getAtomPtr(atom_index);
|
||||
const sym = zig_object.symbol(atom.sym_index);
|
||||
const full_name = try decl.fullyQualifiedName(zcu);
|
||||
const full_name = try decl.fullyQualifiedName(pt);
|
||||
sym.name = try zig_object.string_table.insert(gpa, full_name.toSlice(ip));
|
||||
try atom.code.appendSlice(gpa, code);
|
||||
atom.size = @intCast(code.len);
|
||||
@ -424,17 +424,21 @@ fn createDataSegment(
|
||||
/// For a given `InternPool.DeclIndex` returns its corresponding `Atom.Index`.
|
||||
/// When the index was not found, a new `Atom` will be created, and its index will be returned.
|
||||
/// The newly created Atom is empty with default fields as specified by `Atom.empty`.
|
||||
pub fn getOrCreateAtomForDecl(zig_object: *ZigObject, wasm_file: *Wasm, decl_index: InternPool.DeclIndex) !Atom.Index {
|
||||
const gpa = wasm_file.base.comp.gpa;
|
||||
pub fn getOrCreateAtomForDecl(
|
||||
zig_object: *ZigObject,
|
||||
wasm_file: *Wasm,
|
||||
pt: Zcu.PerThread,
|
||||
decl_index: InternPool.DeclIndex,
|
||||
) !Atom.Index {
|
||||
const gpa = pt.zcu.gpa;
|
||||
const gop = try zig_object.decls_map.getOrPut(gpa, decl_index);
|
||||
if (!gop.found_existing) {
|
||||
const sym_index = try zig_object.allocateSymbol(gpa);
|
||||
gop.value_ptr.* = .{ .atom = try wasm_file.createAtom(sym_index, zig_object.index) };
|
||||
const mod = wasm_file.base.comp.module.?;
|
||||
const decl = mod.declPtr(decl_index);
|
||||
const full_name = try decl.fullyQualifiedName(mod);
|
||||
const decl = pt.zcu.declPtr(decl_index);
|
||||
const full_name = try decl.fullyQualifiedName(pt);
|
||||
const sym = zig_object.symbol(sym_index);
|
||||
sym.name = try zig_object.string_table.insert(gpa, full_name.toSlice(&mod.intern_pool));
|
||||
sym.name = try zig_object.string_table.insert(gpa, full_name.toSlice(&pt.zcu.intern_pool));
|
||||
}
|
||||
return gop.value_ptr.atom;
|
||||
}
|
||||
@ -487,10 +491,10 @@ pub fn lowerUnnamedConst(
|
||||
std.debug.assert(val.typeOf(mod).zigTypeTag(mod) != .Fn); // cannot create local symbols for functions
|
||||
const decl = mod.declPtr(decl_index);
|
||||
|
||||
const parent_atom_index = try zig_object.getOrCreateAtomForDecl(wasm_file, decl_index);
|
||||
const parent_atom_index = try zig_object.getOrCreateAtomForDecl(wasm_file, pt, decl_index);
|
||||
const parent_atom = wasm_file.getAtom(parent_atom_index);
|
||||
const local_index = parent_atom.locals.items.len;
|
||||
const fqn = try decl.fullyQualifiedName(mod);
|
||||
const fqn = try decl.fullyQualifiedName(pt);
|
||||
const name = try std.fmt.allocPrintZ(gpa, "__unnamed_{}_{d}", .{
|
||||
fqn.fmt(&mod.intern_pool), local_index,
|
||||
});
|
||||
@ -775,22 +779,22 @@ pub fn getGlobalSymbol(zig_object: *ZigObject, gpa: std.mem.Allocator, name: []c
|
||||
pub fn getDeclVAddr(
|
||||
zig_object: *ZigObject,
|
||||
wasm_file: *Wasm,
|
||||
pt: Zcu.PerThread,
|
||||
decl_index: InternPool.DeclIndex,
|
||||
reloc_info: link.File.RelocInfo,
|
||||
) !u64 {
|
||||
const target = wasm_file.base.comp.root_mod.resolved_target.result;
|
||||
const gpa = wasm_file.base.comp.gpa;
|
||||
const mod = wasm_file.base.comp.module.?;
|
||||
const decl = mod.declPtr(decl_index);
|
||||
const gpa = pt.zcu.gpa;
|
||||
const decl = pt.zcu.declPtr(decl_index);
|
||||
|
||||
const target_atom_index = try zig_object.getOrCreateAtomForDecl(wasm_file, decl_index);
|
||||
const target_atom_index = try zig_object.getOrCreateAtomForDecl(wasm_file, pt, decl_index);
|
||||
const target_symbol_index = @intFromEnum(wasm_file.getAtom(target_atom_index).sym_index);
|
||||
|
||||
std.debug.assert(reloc_info.parent_atom_index != 0);
|
||||
const atom_index = wasm_file.symbol_atom.get(.{ .file = zig_object.index, .index = @enumFromInt(reloc_info.parent_atom_index) }).?;
|
||||
const atom = wasm_file.getAtomPtr(atom_index);
|
||||
const is_wasm32 = target.cpu.arch == .wasm32;
|
||||
if (decl.typeOf(mod).zigTypeTag(mod) == .Fn) {
|
||||
if (decl.typeOf(pt.zcu).zigTypeTag(pt.zcu) == .Fn) {
|
||||
std.debug.assert(reloc_info.addend == 0); // addend not allowed for function relocations
|
||||
try atom.relocs.append(gpa, .{
|
||||
.index = target_symbol_index,
|
||||
@ -890,7 +894,7 @@ pub fn updateExports(
|
||||
},
|
||||
};
|
||||
const decl = mod.declPtr(decl_index);
|
||||
const atom_index = try zig_object.getOrCreateAtomForDecl(wasm_file, decl_index);
|
||||
const atom_index = try zig_object.getOrCreateAtomForDecl(wasm_file, pt, decl_index);
|
||||
const decl_info = zig_object.decls_map.getPtr(decl_index).?;
|
||||
const atom = wasm_file.getAtom(atom_index);
|
||||
const atom_sym = atom.symbolLoc().getSymbol(wasm_file).*;
|
||||
@ -1116,13 +1120,17 @@ pub fn createDebugSectionForIndex(zig_object: *ZigObject, wasm_file: *Wasm, inde
|
||||
return atom_index;
|
||||
}
|
||||
|
||||
pub fn updateDeclLineNumber(zig_object: *ZigObject, mod: *Zcu, decl_index: InternPool.DeclIndex) !void {
|
||||
pub fn updateDeclLineNumber(
|
||||
zig_object: *ZigObject,
|
||||
pt: Zcu.PerThread,
|
||||
decl_index: InternPool.DeclIndex,
|
||||
) !void {
|
||||
if (zig_object.dwarf) |*dw| {
|
||||
const decl = mod.declPtr(decl_index);
|
||||
const decl_name = try decl.fullyQualifiedName(mod);
|
||||
const decl = pt.zcu.declPtr(decl_index);
|
||||
const decl_name = try decl.fullyQualifiedName(pt);
|
||||
|
||||
log.debug("updateDeclLineNumber {}{*}", .{ decl_name.fmt(&mod.intern_pool), decl });
|
||||
try dw.updateDeclLineNumber(mod, decl_index);
|
||||
log.debug("updateDeclLineNumber {}{*}", .{ decl_name.fmt(&pt.zcu.intern_pool), decl });
|
||||
try dw.updateDeclLineNumber(pt.zcu, decl_index);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -71,7 +71,7 @@ pub const MutableValue = union(enum) {
|
||||
} }),
|
||||
.bytes => |b| try pt.intern(.{ .aggregate = .{
|
||||
.ty = b.ty,
|
||||
.storage = .{ .bytes = try pt.zcu.intern_pool.getOrPutString(pt.zcu.gpa, b.data, .maybe_embedded_nulls) },
|
||||
.storage = .{ .bytes = try pt.zcu.intern_pool.getOrPutString(pt.zcu.gpa, pt.tid, b.data, .maybe_embedded_nulls) },
|
||||
} }),
|
||||
.aggregate => |a| {
|
||||
const elems = try arena.alloc(InternPool.Index, a.elems.len);
|
||||
|
Loading…
Reference in New Issue
Block a user