aboutsummaryrefslogtreecommitdiff
path: root/src/Module.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/Module.zig')
-rw-r--r--src/Module.zig47
1 files changed, 36 insertions, 11 deletions
diff --git a/src/Module.zig b/src/Module.zig
index 71e2bd8d7c..e74d5f1dd8 100644
--- a/src/Module.zig
+++ b/src/Module.zig
@@ -1591,6 +1591,19 @@ pub const Var = struct {
}
};
+pub const DeclAdapter = struct {
+ pub fn hash(self: @This(), s: []const u8) u32 {
+ _ = self;
+ return @truncate(u32, std.hash.Wyhash.hash(0, s));
+ }
+
+ pub fn eql(self: @This(), a: []const u8, b_decl: *Decl, b_index: usize) bool {
+ _ = self;
+ _ = b_index;
+ return mem.eql(u8, a, mem.sliceTo(b_decl.name, 0));
+ }
+};
+
/// The container that structs, enums, unions, and opaques have.
pub const Namespace = struct {
parent: ?*Namespace,
@@ -1601,9 +1614,8 @@ pub const Namespace = struct {
/// which decls have been added/removed from source.
/// Declaration order is preserved via entry order.
/// Key memory is owned by `decl.name`.
- /// TODO save memory with https://github.com/ziglang/zig/issues/8619.
/// Anonymous decls are not stored here; they are kept in `anon_decls` instead.
- decls: std.StringArrayHashMapUnmanaged(*Decl) = .{},
+ decls: std.ArrayHashMapUnmanaged(*Decl, void, DeclContext, true) = .{},
anon_decls: std.AutoArrayHashMapUnmanaged(*Decl, void) = .{},
@@ -1612,6 +1624,19 @@ pub const Namespace = struct {
/// Value is whether the usingnamespace decl is marked `pub`.
usingnamespace_set: std.AutoHashMapUnmanaged(*Decl, bool) = .{},
+ const DeclContext = struct {
+ pub fn hash(self: @This(), decl: *Decl) u32 {
+ _ = self;
+ return @truncate(u32, std.hash.Wyhash.hash(0, mem.sliceTo(decl.name, 0)));
+ }
+
+ pub fn eql(self: @This(), a: *Decl, b: *Decl, b_index: usize) bool {
+ _ = self;
+ _ = b_index;
+ return mem.eql(u8, mem.sliceTo(a.name, 0), mem.sliceTo(b.name, 0));
+ }
+ };
+
pub fn deinit(ns: *Namespace, mod: *Module) void {
ns.destroyDecls(mod);
ns.* = undefined;
@@ -1628,8 +1653,8 @@ pub const Namespace = struct {
var anon_decls = ns.anon_decls;
ns.anon_decls = .{};
- for (decls.values()) |value| {
- value.destroy(mod);
+ for (decls.keys()) |decl| {
+ decl.destroy(mod);
}
decls.deinit(gpa);
@@ -1658,7 +1683,7 @@ pub const Namespace = struct {
// TODO rework this code to not panic on OOM.
// (might want to coordinate with the clearDecl function)
- for (decls.values()) |child_decl| {
+ for (decls.keys()) |child_decl| {
mod.clearDecl(child_decl, outdated_decls) catch @panic("out of memory");
child_decl.destroy(mod);
}
@@ -3325,7 +3350,7 @@ fn updateZirRefs(gpa: Allocator, file: *File, old_zir: Zir) !void {
}
if (decl.getInnerNamespace()) |namespace| {
- for (namespace.decls.values()) |sub_decl| {
+ for (namespace.decls.keys()) |sub_decl| {
try decl_stack.append(gpa, sub_decl);
}
for (namespace.anon_decls.keys()) |sub_decl| {
@@ -4420,7 +4445,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi
if (is_usingnamespace) try namespace.usingnamespace_set.ensureUnusedCapacity(gpa, 1);
// We create a Decl for it regardless of analysis status.
- const gop = try namespace.decls.getOrPut(gpa, decl_name);
+ const gop = try namespace.decls.getOrPutAdapted(gpa, @as([]const u8, mem.sliceTo(decl_name, 0)), DeclAdapter{});
if (!gop.found_existing) {
const new_decl = try mod.allocateNewDecl(decl_name, namespace, decl_node, iter.parent_decl.src_scope);
if (is_usingnamespace) {
@@ -4428,7 +4453,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi
}
log.debug("scan new {*} ({s}) into {*}", .{ new_decl, decl_name, namespace });
new_decl.src_line = line;
- gop.value_ptr.* = new_decl;
+ gop.key_ptr.* = new_decl;
// Exported decls, comptime decls, usingnamespace decls, and
// test decls if in test mode, get analyzed.
const decl_pkg = namespace.file_scope.pkg;
@@ -4464,7 +4489,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi
return;
}
gpa.free(decl_name);
- const decl = gop.value_ptr.*;
+ const decl = gop.key_ptr.*;
log.debug("scan existing {*} ({s}) of {*}", .{ decl, decl.name, namespace });
// Update the AST node of the decl; even if its contents are unchanged, it may
// have been re-ordered.
@@ -5333,7 +5358,7 @@ pub fn processOutdatedAndDeletedDecls(mod: *Module) !void {
// Remove from the namespace it resides in, preserving declaration order.
assert(decl.zir_decl_index != 0);
- _ = decl.src_namespace.decls.orderedRemove(mem.sliceTo(decl.name, 0));
+ _ = decl.src_namespace.decls.orderedRemoveAdapted(@as([]const u8, mem.sliceTo(decl.name, 0)), DeclAdapter{});
try mod.clearDecl(decl, &outdated_decls);
decl.destroy(mod);
@@ -5400,7 +5425,7 @@ pub fn populateTestFunctions(mod: *Module) !void {
const builtin_pkg = mod.main_pkg.table.get("builtin").?;
const builtin_file = (mod.importPkg(builtin_pkg) catch unreachable).file;
const builtin_namespace = builtin_file.root_decl.?.src_namespace;
- const decl = builtin_namespace.decls.get("test_functions").?;
+ const decl = builtin_namespace.decls.getKeyAdapted(@as([]const u8, "test_functions"), DeclAdapter{}).?;
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
const tmp_test_fn_ty = decl.ty.slicePtrFieldType(&buf).elemType();