Skip to content
This repository was archived by the owner on Nov 26, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion src/Scope.zig
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,22 @@ pub const ContainerMemberFns = struct {
container_decl_ptr: *ast.Node,
member_fns: std.ArrayList(*ast.Payload.Func) = .empty,
};
pub const ContainerMemberFnsHashMap = std.AutoArrayHashMapUnmanaged(aro.QualType, ContainerMemberFns);
pub const ContainerMemberFnsHashMap = std.ArrayHashMapUnmanaged(
aro.QualType,
ContainerMemberFns,
struct {
pub fn hash(self: @This(), key: aro.QualType) u32 {
const auto_hash = std.array_hash_map.getAutoHashFn(aro.QualType, @This());
return auto_hash(self, key.unqualified());
}

pub fn eql(self: @This(), a: aro.QualType, b: aro.QualType, b_index: usize) bool {
const auto_eql = std.array_hash_map.getAutoEqlFn(aro.QualType, @This());
return auto_eql(self, a.unqualified(), b.unqualified(), b_index);
}
},
false,
);

id: Id,
parent: ?*Scope,
Expand Down
54 changes: 48 additions & 6 deletions src/Translator.zig
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,46 @@ const MacroTranslator = @import("MacroTranslator.zig");
const PatternList = @import("PatternList.zig");
const Scope = @import("Scope.zig");

const AnonymousRecordFieldNames = struct {
pub const Key = struct {
parent: QualType,
field: QualType,
};

pub const Context = struct {
pub fn hash(ctx: Context, key: Key) u64 {
const auto_hash = std.hash_map.getAutoHashFn(Key, Context);
return auto_hash(ctx, .{
.parent = key.parent.unqualified(),
.field = key.field.unqualified(),
});
}

pub fn eql(ctx: Context, a: Key, b: Key) bool {
const auto_eql = std.hash_map.getAutoEqlFn(Key, Context);
return auto_eql(ctx, .{
.parent = a.parent.unqualified(),
.field = a.field.unqualified(),
}, .{
.parent = b.parent.unqualified(),
.field = b.field.unqualified(),
});
}
};
};

pub const QualTypeHashContext = struct {
pub fn hash(ctx: QualTypeHashContext, key: QualType) u64 {
const auto_hash = std.hash_map.getAutoHashFn(QualType, QualTypeHashContext);
return auto_hash(ctx, key.unqualified());
}

pub fn eql(ctx: QualTypeHashContext, a: QualType, b: QualType) bool {
const auto_eql = std.hash_map.getAutoEqlFn(QualType, QualTypeHashContext);
return auto_eql(ctx, a.unqualified(), b.unqualified());
}
};

pub const Error = std.mem.Allocator.Error;
pub const MacroProcessingError = Error || error{UnexpectedMacroToken};
pub const TypeError = Error || error{UnsupportedType};
Expand All @@ -44,14 +84,16 @@ mangle_count: u32 = 0,
/// Table of declarations for enum, struct, union and typedef types.
type_decls: std.AutoArrayHashMapUnmanaged(Node.Index, []const u8) = .empty,
/// Table of record decls that have been demoted to opaques.
opaque_demotes: std.AutoHashMapUnmanaged(QualType, void) = .empty,
opaque_demotes: std.HashMapUnmanaged(QualType, void, QualTypeHashContext, std.hash_map.default_max_load_percentage) = .empty,
/// Table of unnamed enums and records that are child types of typedefs.
unnamed_typedefs: std.AutoHashMapUnmanaged(QualType, []const u8) = .empty,
unnamed_typedefs: std.HashMapUnmanaged(QualType, []const u8, QualTypeHashContext, std.hash_map.default_max_load_percentage) = .empty,
/// Table of anonymous record to generated field names.
anonymous_record_field_names: std.AutoHashMapUnmanaged(struct {
parent: QualType,
field: QualType,
}, []const u8) = .empty,
anonymous_record_field_names: std.HashMapUnmanaged(
AnonymousRecordFieldNames.Key,
[]const u8,
AnonymousRecordFieldNames.Context,
std.hash_map.default_max_load_percentage,
) = .empty,

/// This one is different than the root scope's name table. This contains
/// a list of names that we found by visiting all the top level decls without
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#define SUFFIXED(x) x##_suffix

struct my_struct {
union {
int SUFFIXED(internal);
double d;
};
};

int my_func(const struct my_struct* s) {
return s->SUFFIXED(internal);
}

// translate
//
// const union_unnamed_1 = extern union {
// internal_suffix: c_int,
// d: f64,
// };
// pub const struct_my_struct = extern struct {
// unnamed_0: union_unnamed_1 = @import("std").mem.zeroes(union_unnamed_1),
// pub const my_func = __root.my_func;
// pub const func = __root.my_func;
// };
// pub export fn my_func(arg_s: [*c]const struct_my_struct) c_int {
// var s = arg_s;
// _ = &s;
// return s.*.unnamed_0.internal_suffix;
// }
15 changes: 15 additions & 0 deletions test/cases/translate/member_with_const_qualifier.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
struct Foo {
int a;
};
extern int foo(const struct Foo *);
extern int bar(struct Foo *);

// translate
//
// pub const struct_Foo = extern struct {
// a: c_int = 0,
// pub const foo = __root.foo;
// pub const bar = __root.bar;
// };
// pub extern fn foo([*c]const struct_Foo) c_int;
// pub extern fn bar([*c]struct_Foo) c_int;