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:
@@ -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 {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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(.{})");
|
||||
}
|
||||
|
||||
51
src/Zcu.zig
51
src/Zcu.zig
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user