From 83d2d7ab8afed6d24238dbb2696fb5bc35cdb05d Mon Sep 17 00:00:00 2001 From: Tadeo Kondrak Date: Tue, 28 Apr 2020 07:30:24 -0600 Subject: [PATCH 1/2] Mangle field names with a local counter in records See https://github.com/ifreund/river/issues/17 for an issue that occurs because the field names are mangled globally. When using the generated bindings, you have no choice but to use the unstable names or redeclare the entire struct. This commit changes the behaviour to use a local counter per record declaration, so the names are predictable each time. --- src-self-hosted/translate_c.zig | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index 8b137c4d97..853c2bef5b 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -788,6 +788,7 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?* .rbrace_token = undefined, }; + var unnamed_field_count: u32 = 0; var it = ZigClangRecordDecl_field_begin(record_def); const end_it = ZigClangRecordDecl_field_end(record_def); while (ZigClangRecordDecl_field_iterator_neq(it, end_it)) : (it = ZigClangRecordDecl_field_iterator_next(it)) { @@ -812,7 +813,9 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?* var is_anon = false; var raw_name = try c.str(ZigClangNamedDecl_getName_bytes_begin(@ptrCast(*const ZigClangNamedDecl, field_decl))); if (ZigClangFieldDecl_isAnonymousStructOrUnion(field_decl) or raw_name.len == 0) { - raw_name = try std.fmt.allocPrint(c.a(), "unnamed_{}", .{c.getMangle()}); + // Context.getMangle() is not used here because doing so causes unpredictable field names for anonymous fields. + raw_name = try std.fmt.allocPrint(c.a(), "unnamed_{}", .{unnamed_field_count}); + unnamed_field_count += 1; is_anon = true; } const field_name = try appendIdentifier(c, raw_name); From 0cf129689eba47033bc86adf4fcd45dabe5ef04c Mon Sep 17 00:00:00 2001 From: Tadeo Kondrak Date: Tue, 28 Apr 2020 07:41:49 -0600 Subject: [PATCH 2/2] Fix/add translate-c tests for previous commit --- test/translate_c.zig | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/test/translate_c.zig b/test/translate_c.zig index 377e4e3fd8..2c2f9ac364 100644 --- a/test/translate_c.zig +++ b/test/translate_c.zig @@ -189,20 +189,20 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\} outer; \\void foo(outer *x) { x->y = x->x; } , &[_][]const u8{ - \\const struct_unnamed_5 = extern struct { + \\const struct_unnamed_3 = extern struct { \\ y: c_int, \\}; - \\const union_unnamed_3 = extern union { + \\const union_unnamed_2 = extern union { \\ x: u8, - \\ unnamed_4: struct_unnamed_5, + \\ unnamed_0: struct_unnamed_3, \\}; \\const struct_unnamed_1 = extern struct { - \\ unnamed_2: union_unnamed_3, + \\ unnamed_0: union_unnamed_2, \\}; \\pub const outer = struct_unnamed_1; \\pub export fn foo(arg_x: [*c]outer) void { \\ var x = arg_x; - \\ x.*.unnamed_2.unnamed_4.y = @bitCast(c_int, @as(c_uint, x.*.unnamed_2.x)); + \\ x.*.unnamed_0.unnamed_0.y = @bitCast(c_int, @as(c_uint, x.*.unnamed_0.x)); \\} }); @@ -2922,7 +2922,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\}; \\pub const NAMED = struct_NAMED; \\pub const struct_ONENAMEWITHSTRUCT = extern struct { - \\ unnamed_1: struct_NAMED, + \\ unnamed_0: struct_NAMED, \\ b: c_long, \\}; }); @@ -2948,4 +2948,22 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\}; }); } + + cases.add("unnamed fields have predictabile names", + \\struct a { + \\ struct {}; + \\}; + \\struct b { + \\ struct {}; + \\}; + , &[_][]const u8{ + \\const struct_unnamed_1 = extern struct {}; + \\pub const struct_a = extern struct { + \\ unnamed_0: struct_unnamed_1, + \\}; + \\const struct_unnamed_2 = extern struct {}; + \\pub const struct_b = extern struct { + \\ unnamed_0: struct_unnamed_2, + \\}; + }); }