authorgravatar for 35231115+Rocknest@users.noreply.github.comRocknest <35231115+Rocknest@users.noreply.github.com> 2020-01-09 20:38:31+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-01-09 13:38:31-05:00
log4613e4d15f85406d23f91134a9ec5854da33965f
tree570fcbce0c76228deb9d955cc800630569713b0b
parent834218d789430ac238e5ef4fa99cfe4bcf006f2d

Fix C struct with function pointer member and typedefs mistranslated (#4122)

fixes #4118

2 files changed, 24 insertions(+), 4 deletions(-)

src-self-hosted/translate_c.zig+8-4
...@@ -392,7 +392,7 @@ fn declVisitor(c: *Context, decl: *const ZigClangDecl) Error!void {...@@ -392,7 +392,7 @@ fn declVisitor(c: *Context, decl: *const ZigClangDecl) Error!void {
392 return visitFnDecl(c, @ptrCast(*const ZigClangFunctionDecl, decl));392 return visitFnDecl(c, @ptrCast(*const ZigClangFunctionDecl, decl));
393 },393 },
394 .Typedef => {394 .Typedef => {
395 _ = try transTypeDef(c, @ptrCast(*const ZigClangTypedefNameDecl, decl));395 _ = try transTypeDef(c, @ptrCast(*const ZigClangTypedefNameDecl, decl), true);
396 },396 },
397 .Enum => {397 .Enum => {
398 _ = try transEnumDecl(c, @ptrCast(*const ZigClangEnumDecl, decl));398 _ = try transEnumDecl(c, @ptrCast(*const ZigClangEnumDecl, decl));
...@@ -636,9 +636,9 @@ fn transTypeDefAsBuiltin(c: *Context, typedef_decl: *const ZigClangTypedefNameDe...@@ -636,9 +636,9 @@ fn transTypeDefAsBuiltin(c: *Context, typedef_decl: *const ZigClangTypedefNameDe
636 return transCreateNodeIdentifier(c, builtin_name);636 return transCreateNodeIdentifier(c, builtin_name);
637}637}
638638
639fn transTypeDef(c: *Context, typedef_decl: *const ZigClangTypedefNameDecl) Error!?*ast.Node {639fn transTypeDef(c: *Context, typedef_decl: *const ZigClangTypedefNameDecl, top_level_visit: bool) Error!?*ast.Node {
640 if (c.decl_table.get(@ptrToInt(ZigClangTypedefNameDecl_getCanonicalDecl(typedef_decl)))) |kv|640 if (c.decl_table.get(@ptrToInt(ZigClangTypedefNameDecl_getCanonicalDecl(typedef_decl)))) |kv|
641 return try transCreateNodeIdentifier(c, kv.value); // Avoid processing this decl twice641 return transCreateNodeIdentifier(c, kv.value); // Avoid processing this decl twice
642 const rp = makeRestorePoint(c);642 const rp = makeRestorePoint(c);
643643
644 const typedef_name = try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, typedef_decl)));644 const typedef_name = try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, typedef_decl)));
...@@ -671,6 +671,10 @@ fn transTypeDef(c: *Context, typedef_decl: *const ZigClangTypedefNameDecl) Error...@@ -671,6 +671,10 @@ fn transTypeDef(c: *Context, typedef_decl: *const ZigClangTypedefNameDecl) Error
671 return transTypeDefAsBuiltin(c, typedef_decl, "isize")671 return transTypeDefAsBuiltin(c, typedef_decl, "isize")
672 else if (mem.eql(u8, checked_name, "size_t"))672 else if (mem.eql(u8, checked_name, "size_t"))
673 return transTypeDefAsBuiltin(c, typedef_decl, "usize");673 return transTypeDefAsBuiltin(c, typedef_decl, "usize");
674
675 if (!top_level_visit) {
676 return transCreateNodeIdentifier(c, checked_name);
677 }
674678
675 _ = try c.decl_table.put(@ptrToInt(ZigClangTypedefNameDecl_getCanonicalDecl(typedef_decl)), checked_name);679 _ = try c.decl_table.put(@ptrToInt(ZigClangTypedefNameDecl_getCanonicalDecl(typedef_decl)), checked_name);
676 const visib_tok = try appendToken(c, .Keyword_pub, "pub");680 const visib_tok = try appendToken(c, .Keyword_pub, "pub");
...@@ -4299,7 +4303,7 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour...@@ -4299,7 +4303,7 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour
4299 const typedef_ty = @ptrCast(*const ZigClangTypedefType, ty);4303 const typedef_ty = @ptrCast(*const ZigClangTypedefType, ty);
43004304
4301 const typedef_decl = ZigClangTypedefType_getDecl(typedef_ty);4305 const typedef_decl = ZigClangTypedefType_getDecl(typedef_ty);
4302 return (try transTypeDef(rp.c, typedef_decl)) orelse4306 return (try transTypeDef(rp.c, typedef_decl, false)) orelse
4303 revertAndWarn(rp, error.UnsupportedType, source_loc, "unable to translate typedef declaration", .{});4307 revertAndWarn(rp, error.UnsupportedType, source_loc, "unable to translate typedef declaration", .{});
4304 },4308 },
4305 .Record => {4309 .Record => {
test/run_translated_c.zig+16
...@@ -3,6 +3,22 @@ const tests = @import("tests.zig");...@@ -3,6 +3,22 @@ const tests = @import("tests.zig");
3const nl = std.cstr.line_sep;3const nl = std.cstr.line_sep;
44
5pub fn addCases(cases: *tests.RunTranslatedCContext) void {5pub fn addCases(cases: *tests.RunTranslatedCContext) void {
6 cases.add("typedef and function pointer",
7 \\#include <stdlib.h>
8 \\typedef struct _Foo Foo;
9 \\typedef int Ret;
10 \\typedef int Param;
11 \\struct _Foo { Ret (*func)(Param p); };
12 \\static Ret add1(Param p) {
13 \\ return p + 1;
14 \\}
15 \\int main(int argc, char **argv) {
16 \\ Foo strct = { .func = add1 };
17 \\ if (strct.func(16) != 17) abort();
18 \\ return 0;
19 \\}
20 , "");
21
6 cases.add("ternary operator",22 cases.add("ternary operator",
7 \\#include <stdlib.h>23 \\#include <stdlib.h>
8 \\static int cnt = 0;24 \\static int cnt = 0;