InternPool: fix undefined decl fully qualified name

This is now possible after moving `File.Index` to `*File` mapping into
intern pool.
This commit is contained in:
Jacob Young
2024-07-10 10:17:32 -04:00
parent 3d2dfbe828
commit 8f292431b0
5 changed files with 34 additions and 32 deletions

View File

@@ -8030,6 +8030,8 @@ fn finishFuncInstance(
decl.name = try ip.getOrPutStringFmt(gpa, tid, "{}__anon_{d}", .{
fn_owner_decl.name.fmt(ip), @intFromEnum(decl_index),
}, .no_embedded_nulls);
decl.fqn = try ip.namespacePtr(fn_owner_decl.src_namespace)
.internFullyQualifiedName(ip, gpa, tid, decl.name);
}
pub const EnumTypeInit = struct {

View File

@@ -9737,9 +9737,6 @@ fn funcCommon(
.generic_owner = sema.generic_owner,
.comptime_args = sema.comptime_args,
});
const func_decl = mod.declPtr(ip.indexToKey(func_index).func.owner_decl);
func_decl.fqn =
try ip.namespacePtr(func_decl.src_namespace).internFullyQualifiedName(pt, func_decl.name);
return finishFunc(
sema,
block,

View File

@@ -337,7 +337,7 @@ pub fn print(ty: Type, writer: anytype, pt: Zcu.PerThread) @TypeOf(writer).Error
try writer.print("{}", .{decl.fqn.fmt(ip)});
} else if (ip.loadStructType(ty.toIntern()).namespace.unwrap()) |namespace_index| {
const namespace = mod.namespacePtr(namespace_index);
try namespace.renderFullyQualifiedName(mod, .empty, writer);
try namespace.renderFullyQualifiedName(ip, .empty, writer);
} else {
try writer.writeAll("@TypeOf(.{})");
}

View File

@@ -628,23 +628,27 @@ pub const Namespace = struct {
return zcu.fileByIndex(ns.file_scope);
}
pub fn fileScopeIp(ns: Namespace, ip: *InternPool) *File {
return ip.filePtr(ns.file_scope);
}
// This renders e.g. "std.fs.Dir.OpenOptions"
pub fn renderFullyQualifiedName(
ns: Namespace,
zcu: *Zcu,
ip: *InternPool,
name: InternPool.NullTerminatedString,
writer: anytype,
) @TypeOf(writer).Error!void {
if (ns.parent.unwrap()) |parent| {
try zcu.namespacePtr(parent).renderFullyQualifiedName(
zcu,
zcu.declPtr(ns.decl_index).name,
try ip.namespacePtr(parent).renderFullyQualifiedName(
ip,
ip.declPtr(ns.decl_index).name,
writer,
);
} else {
try ns.fileScope(zcu).renderFullyQualifiedName(writer);
try ns.fileScopeIp(ip).renderFullyQualifiedName(writer);
}
if (name != .empty) try writer.print(".{}", .{name.fmt(&zcu.intern_pool)});
if (name != .empty) try writer.print(".{}", .{name.fmt(ip)});
}
/// This renders e.g. "std/fs.zig:Dir.OpenOptions"
@@ -670,44 +674,43 @@ pub const Namespace = struct {
pub fn internFullyQualifiedName(
ns: Namespace,
pt: Zcu.PerThread,
ip: *InternPool,
gpa: Allocator,
tid: Zcu.PerThread.Id,
name: InternPool.NullTerminatedString,
) !InternPool.NullTerminatedString {
const zcu = pt.zcu;
const ip = &zcu.intern_pool;
const gpa = zcu.gpa;
const strings = ip.getLocal(pt.tid).getMutableStrings(gpa);
const strings = ip.getLocal(tid).getMutableStrings(gpa);
// Protects reads of interned strings from being reallocated during the call to
// renderFullyQualifiedName.
const slice = try strings.addManyAsSlice(count: {
var count: usize = name.length(ip) + 1;
var cur_ns = &ns;
while (true) {
const decl = zcu.declPtr(cur_ns.decl_index);
cur_ns = zcu.namespacePtr(cur_ns.parent.unwrap() orelse {
count += ns.fileScope(zcu).fullyQualifiedNameLen();
const decl = ip.declPtr(cur_ns.decl_index);
cur_ns = ip.namespacePtr(cur_ns.parent.unwrap() orelse {
count += ns.fileScopeIp(ip).fullyQualifiedNameLen();
break :count count;
});
count += decl.name.length(ip) + 1;
}
});
var fbs = std.io.fixedBufferStream(slice[0]);
ns.renderFullyQualifiedName(zcu, name, fbs.writer()) catch unreachable;
ns.renderFullyQualifiedName(ip, name, fbs.writer()) catch unreachable;
assert(fbs.pos == slice[0].len);
// Sanitize the name for nvptx which is more restrictive.
// TODO This should be handled by the backend, not the frontend. Have a
// look at how the C backend does it for inspiration.
const cpu_arch = zcu.root_mod.resolved_target.result.cpu.arch;
if (cpu_arch.isNvptx()) {
for (slice[0]) |*byte| switch (byte.*) {
'{', '}', '*', '[', ']', '(', ')', ',', ' ', '\'' => byte.* = '_',
else => {},
};
}
// FIXME This has bitrotted and is no longer able to be implemented here.
//const cpu_arch = zcu.root_mod.resolved_target.result.cpu.arch;
//if (cpu_arch.isNvptx()) {
// for (slice[0]) |*byte| switch (byte.*) {
// '{', '}', '*', '[', ']', '(', ')', ',', ' ', '\'' => byte.* = '_',
// else => {},
// };
//}
return ip.getOrPutTrailingString(gpa, pt.tid, @intCast(slice[0].len), .no_embedded_nulls);
return ip.getOrPutTrailingString(gpa, tid, @intCast(slice[0].len), .no_embedded_nulls);
}
pub fn getType(ns: Namespace, zcu: *Zcu) Type {

View File

@@ -1896,7 +1896,7 @@ const ScanDeclIter = struct {
const was_exported = decl.is_exported;
assert(decl.kind == kind); // ZIR tracking should preserve this
decl.name = decl_name;
decl.fqn = try namespace.internFullyQualifiedName(pt, decl_name);
decl.fqn = try namespace.internFullyQualifiedName(ip, gpa, pt.tid, decl_name);
decl.is_pub = declaration.flags.is_pub;
decl.is_exported = declaration.flags.is_export;
break :decl_index .{ was_exported, decl_index };
@@ -1906,7 +1906,7 @@ const ScanDeclIter = struct {
const new_decl = zcu.declPtr(new_decl_index);
new_decl.kind = kind;
new_decl.name = decl_name;
new_decl.fqn = try namespace.internFullyQualifiedName(pt, decl_name);
new_decl.fqn = try namespace.internFullyQualifiedName(ip, gpa, pt.tid, 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();
@@ -2279,8 +2279,8 @@ pub fn initNewAnonDecl(
const new_decl = pt.zcu.declPtr(new_decl_index);
new_decl.name = name;
new_decl.fqn = fqn.unwrap() orelse
try pt.zcu.namespacePtr(new_decl.src_namespace).internFullyQualifiedName(pt, name);
new_decl.fqn = fqn.unwrap() orelse try pt.zcu.namespacePtr(new_decl.src_namespace)
.internFullyQualifiedName(&pt.zcu.intern_pool, pt.zcu.gpa, pt.tid, name);
new_decl.val = val;
new_decl.alignment = .none;
new_decl.@"linksection" = .none;