authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-04-28 23:18:36+03:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2020-04-28 23:18:36+03:00
logdb25c78413ac4472c6d50122d96c85a42dc032bc
tree40aa138a2c1b24712af90870112cd3c0ea1fb845
parent01605a77428aefedbdf76830b6e4cab4853f2e4e
parent0cf129689eba47033bc86adf4fcd45dabe5ef04c
signature Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #5201 from tadeokondrak/mangle-field-names-locally

Mangle field names with a local counter in records (translate-c)

2 files changed, 28 insertions(+), 7 deletions(-)

src-self-hosted/translate_c.zig+4-1
...@@ -788,6 +788,7 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?*...@@ -788,6 +788,7 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?*
788 .rbrace_token = undefined,788 .rbrace_token = undefined,
789 };789 };
790790
791 var unnamed_field_count: u32 = 0;
791 var it = ZigClangRecordDecl_field_begin(record_def);792 var it = ZigClangRecordDecl_field_begin(record_def);
792 const end_it = ZigClangRecordDecl_field_end(record_def);793 const end_it = ZigClangRecordDecl_field_end(record_def);
793 while (ZigClangRecordDecl_field_iterator_neq(it, end_it)) : (it = ZigClangRecordDecl_field_iterator_next(it)) {794 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!?*...@@ -812,7 +813,9 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?*
812 var is_anon = false;813 var is_anon = false;
813 var raw_name = try c.str(ZigClangNamedDecl_getName_bytes_begin(@ptrCast(*const ZigClangNamedDecl, field_decl)));814 var raw_name = try c.str(ZigClangNamedDecl_getName_bytes_begin(@ptrCast(*const ZigClangNamedDecl, field_decl)));
814 if (ZigClangFieldDecl_isAnonymousStructOrUnion(field_decl) or raw_name.len == 0) {815 if (ZigClangFieldDecl_isAnonymousStructOrUnion(field_decl) or raw_name.len == 0) {
815 raw_name = try std.fmt.allocPrint(c.a(), "unnamed_{}", .{c.getMangle()});816 // Context.getMangle() is not used here because doing so causes unpredictable field names for anonymous fields.
817 raw_name = try std.fmt.allocPrint(c.a(), "unnamed_{}", .{unnamed_field_count});
818 unnamed_field_count += 1;
816 is_anon = true;819 is_anon = true;
817 }820 }
818 const field_name = try appendIdentifier(c, raw_name);821 const field_name = try appendIdentifier(c, raw_name);
test/translate_c.zig+24-6
...@@ -189,20 +189,20 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -189,20 +189,20 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
189 \\} outer;189 \\} outer;
190 \\void foo(outer *x) { x->y = x->x; }190 \\void foo(outer *x) { x->y = x->x; }
191 , &[_][]const u8{191 , &[_][]const u8{
192 \\const struct_unnamed_5 = extern struct {192 \\const struct_unnamed_3 = extern struct {
193 \\ y: c_int,193 \\ y: c_int,
194 \\};194 \\};
195 \\const union_unnamed_3 = extern union {195 \\const union_unnamed_2 = extern union {
196 \\ x: u8,196 \\ x: u8,
197 \\ unnamed_4: struct_unnamed_5,197 \\ unnamed_0: struct_unnamed_3,
198 \\};198 \\};
199 \\const struct_unnamed_1 = extern struct {199 \\const struct_unnamed_1 = extern struct {
200 \\ unnamed_2: union_unnamed_3,200 \\ unnamed_0: union_unnamed_2,
201 \\};201 \\};
202 \\pub const outer = struct_unnamed_1;202 \\pub const outer = struct_unnamed_1;
203 \\pub export fn foo(arg_x: [*c]outer) void {203 \\pub export fn foo(arg_x: [*c]outer) void {
204 \\ var x = arg_x;204 \\ var x = arg_x;
205 \\ x.*.unnamed_2.unnamed_4.y = @bitCast(c_int, @as(c_uint, x.*.unnamed_2.x));205 \\ x.*.unnamed_0.unnamed_0.y = @bitCast(c_int, @as(c_uint, x.*.unnamed_0.x));
206 \\}206 \\}
207 });207 });
208208
...@@ -2922,7 +2922,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -2922,7 +2922,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
2922 \\};2922 \\};
2923 \\pub const NAMED = struct_NAMED;2923 \\pub const NAMED = struct_NAMED;
2924 \\pub const struct_ONENAMEWITHSTRUCT = extern struct {2924 \\pub const struct_ONENAMEWITHSTRUCT = extern struct {
2925 \\ unnamed_1: struct_NAMED,2925 \\ unnamed_0: struct_NAMED,
2926 \\ b: c_long,2926 \\ b: c_long,
2927 \\};2927 \\};
2928 });2928 });
...@@ -2948,4 +2948,22 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -2948,4 +2948,22 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
2948 \\};2948 \\};
2949 });2949 });
2950 }2950 }
2951
2952 cases.add("unnamed fields have predictabile names",
2953 \\struct a {
2954 \\ struct {};
2955 \\};
2956 \\struct b {
2957 \\ struct {};
2958 \\};
2959 , &[_][]const u8{
2960 \\const struct_unnamed_1 = extern struct {};
2961 \\pub const struct_a = extern struct {
2962 \\ unnamed_0: struct_unnamed_1,
2963 \\};
2964 \\const struct_unnamed_2 = extern struct {};
2965 \\pub const struct_b = extern struct {
2966 \\ unnamed_0: struct_unnamed_2,
2967 \\};
2968 });
2951}2969}