Skip to content
This repository was archived by the owner on Nov 26, 2025. It is now read-only.

Commit a369b97

Browse files
authored
Ignore qualifiers when hashing aro.QualType
Closes #228
1 parent 5fde64e commit a369b97

4 files changed

Lines changed: 108 additions & 7 deletions

File tree

src/Scope.zig

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,22 @@ pub const ContainerMemberFns = struct {
1818
container_decl_ptr: *ast.Node,
1919
member_fns: std.ArrayList(*ast.Payload.Func) = .empty,
2020
};
21-
pub const ContainerMemberFnsHashMap = std.AutoArrayHashMapUnmanaged(aro.QualType, ContainerMemberFns);
21+
pub const ContainerMemberFnsHashMap = std.ArrayHashMapUnmanaged(
22+
aro.QualType,
23+
ContainerMemberFns,
24+
struct {
25+
pub fn hash(self: @This(), key: aro.QualType) u32 {
26+
const auto_hash = std.array_hash_map.getAutoHashFn(aro.QualType, @This());
27+
return auto_hash(self, key.unqualified());
28+
}
29+
30+
pub fn eql(self: @This(), a: aro.QualType, b: aro.QualType, b_index: usize) bool {
31+
const auto_eql = std.array_hash_map.getAutoEqlFn(aro.QualType, @This());
32+
return auto_eql(self, a.unqualified(), b.unqualified(), b_index);
33+
}
34+
},
35+
false,
36+
);
2237

2338
id: Id,
2439
parent: ?*Scope,

src/Translator.zig

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,46 @@ const MacroTranslator = @import("MacroTranslator.zig");
1919
const PatternList = @import("PatternList.zig");
2020
const Scope = @import("Scope.zig");
2121

22+
const AnonymousRecordFieldNames = struct {
23+
pub const Key = struct {
24+
parent: QualType,
25+
field: QualType,
26+
};
27+
28+
pub const Context = struct {
29+
pub fn hash(ctx: Context, key: Key) u64 {
30+
const auto_hash = std.hash_map.getAutoHashFn(Key, Context);
31+
return auto_hash(ctx, .{
32+
.parent = key.parent.unqualified(),
33+
.field = key.field.unqualified(),
34+
});
35+
}
36+
37+
pub fn eql(ctx: Context, a: Key, b: Key) bool {
38+
const auto_eql = std.hash_map.getAutoEqlFn(Key, Context);
39+
return auto_eql(ctx, .{
40+
.parent = a.parent.unqualified(),
41+
.field = a.field.unqualified(),
42+
}, .{
43+
.parent = b.parent.unqualified(),
44+
.field = b.field.unqualified(),
45+
});
46+
}
47+
};
48+
};
49+
50+
pub const QualTypeHashContext = struct {
51+
pub fn hash(ctx: QualTypeHashContext, key: QualType) u64 {
52+
const auto_hash = std.hash_map.getAutoHashFn(QualType, QualTypeHashContext);
53+
return auto_hash(ctx, key.unqualified());
54+
}
55+
56+
pub fn eql(ctx: QualTypeHashContext, a: QualType, b: QualType) bool {
57+
const auto_eql = std.hash_map.getAutoEqlFn(QualType, QualTypeHashContext);
58+
return auto_eql(ctx, a.unqualified(), b.unqualified());
59+
}
60+
};
61+
2262
pub const Error = std.mem.Allocator.Error;
2363
pub const MacroProcessingError = Error || error{UnexpectedMacroToken};
2464
pub const TypeError = Error || error{UnsupportedType};
@@ -44,14 +84,16 @@ mangle_count: u32 = 0,
4484
/// Table of declarations for enum, struct, union and typedef types.
4585
type_decls: std.AutoArrayHashMapUnmanaged(Node.Index, []const u8) = .empty,
4686
/// Table of record decls that have been demoted to opaques.
47-
opaque_demotes: std.AutoHashMapUnmanaged(QualType, void) = .empty,
87+
opaque_demotes: std.HashMapUnmanaged(QualType, void, QualTypeHashContext, std.hash_map.default_max_load_percentage) = .empty,
4888
/// Table of unnamed enums and records that are child types of typedefs.
49-
unnamed_typedefs: std.AutoHashMapUnmanaged(QualType, []const u8) = .empty,
89+
unnamed_typedefs: std.HashMapUnmanaged(QualType, []const u8, QualTypeHashContext, std.hash_map.default_max_load_percentage) = .empty,
5090
/// Table of anonymous record to generated field names.
51-
anonymous_record_field_names: std.AutoHashMapUnmanaged(struct {
52-
parent: QualType,
53-
field: QualType,
54-
}, []const u8) = .empty,
91+
anonymous_record_field_names: std.HashMapUnmanaged(
92+
AnonymousRecordFieldNames.Key,
93+
[]const u8,
94+
AnonymousRecordFieldNames.Context,
95+
std.hash_map.default_max_load_percentage,
96+
) = .empty,
5597

5698
/// This one is different than the root scope's name table. This contains
5799
/// a list of names that we found by visiting all the top level decls without
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#define SUFFIXED(x) x##_suffix
2+
3+
struct my_struct {
4+
union {
5+
int SUFFIXED(internal);
6+
double d;
7+
};
8+
};
9+
10+
int my_func(const struct my_struct* s) {
11+
return s->SUFFIXED(internal);
12+
}
13+
14+
// translate
15+
//
16+
// const union_unnamed_1 = extern union {
17+
// internal_suffix: c_int,
18+
// d: f64,
19+
// };
20+
// pub const struct_my_struct = extern struct {
21+
// unnamed_0: union_unnamed_1 = @import("std").mem.zeroes(union_unnamed_1),
22+
// pub const my_func = __root.my_func;
23+
// pub const func = __root.my_func;
24+
// };
25+
// pub export fn my_func(arg_s: [*c]const struct_my_struct) c_int {
26+
// var s = arg_s;
27+
// _ = &s;
28+
// return s.*.unnamed_0.internal_suffix;
29+
// }
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
struct Foo {
2+
int a;
3+
};
4+
extern int foo(const struct Foo *);
5+
extern int bar(struct Foo *);
6+
7+
// translate
8+
//
9+
// pub const struct_Foo = extern struct {
10+
// a: c_int = 0,
11+
// pub const foo = __root.foo;
12+
// pub const bar = __root.bar;
13+
// };
14+
// pub extern fn foo([*c]const struct_Foo) c_int;
15+
// pub extern fn bar([*c]struct_Foo) c_int;

0 commit comments

Comments
 (0)