From 4613e4d15f85406d23f91134a9ec5854da33965f Mon Sep 17 00:00:00 2001 From: Rocknest <35231115+Rocknest@users.noreply.github.com> Date: Thu, 9 Jan 2020 20:38:31 +0200 Subject: [PATCH] Fix C struct with function pointer member and typedefs mistranslated (#4122) fixes #4118 --- src-self-hosted/translate_c.zig | 12 ++++++++---- test/run_translated_c.zig | 16 ++++++++++++++++ 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index 8223d5b265..519cb4f1da 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -392,7 +392,7 @@ fn declVisitor(c: *Context, decl: *const ZigClangDecl) Error!void { return visitFnDecl(c, @ptrCast(*const ZigClangFunctionDecl, decl)); }, .Typedef => { - _ = try transTypeDef(c, @ptrCast(*const ZigClangTypedefNameDecl, decl)); + _ = try transTypeDef(c, @ptrCast(*const ZigClangTypedefNameDecl, decl), true); }, .Enum => { _ = try transEnumDecl(c, @ptrCast(*const ZigClangEnumDecl, decl)); @@ -636,9 +636,9 @@ fn transTypeDefAsBuiltin(c: *Context, typedef_decl: *const ZigClangTypedefNameDe return transCreateNodeIdentifier(c, builtin_name); } -fn transTypeDef(c: *Context, typedef_decl: *const ZigClangTypedefNameDecl) Error!?*ast.Node { +fn transTypeDef(c: *Context, typedef_decl: *const ZigClangTypedefNameDecl, top_level_visit: bool) Error!?*ast.Node { if (c.decl_table.get(@ptrToInt(ZigClangTypedefNameDecl_getCanonicalDecl(typedef_decl)))) |kv| - return try transCreateNodeIdentifier(c, kv.value); // Avoid processing this decl twice + return transCreateNodeIdentifier(c, kv.value); // Avoid processing this decl twice const rp = makeRestorePoint(c); 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 return transTypeDefAsBuiltin(c, typedef_decl, "isize") else if (mem.eql(u8, checked_name, "size_t")) return transTypeDefAsBuiltin(c, typedef_decl, "usize"); + + if (!top_level_visit) { + return transCreateNodeIdentifier(c, checked_name); + } _ = try c.decl_table.put(@ptrToInt(ZigClangTypedefNameDecl_getCanonicalDecl(typedef_decl)), checked_name); const visib_tok = try appendToken(c, .Keyword_pub, "pub"); @@ -4299,7 +4303,7 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour const typedef_ty = @ptrCast(*const ZigClangTypedefType, ty); const typedef_decl = ZigClangTypedefType_getDecl(typedef_ty); - return (try transTypeDef(rp.c, typedef_decl)) orelse + return (try transTypeDef(rp.c, typedef_decl, false)) orelse revertAndWarn(rp, error.UnsupportedType, source_loc, "unable to translate typedef declaration", .{}); }, .Record => { diff --git a/test/run_translated_c.zig b/test/run_translated_c.zig index 093734e60c..5d8233ec96 100644 --- a/test/run_translated_c.zig +++ b/test/run_translated_c.zig @@ -3,6 +3,22 @@ const tests = @import("tests.zig"); const nl = std.cstr.line_sep; pub fn addCases(cases: *tests.RunTranslatedCContext) void { + cases.add("typedef and function pointer", + \\#include + \\typedef struct _Foo Foo; + \\typedef int Ret; + \\typedef int Param; + \\struct _Foo { Ret (*func)(Param p); }; + \\static Ret add1(Param p) { + \\ return p + 1; + \\} + \\int main(int argc, char **argv) { + \\ Foo strct = { .func = add1 }; + \\ if (strct.func(16) != 17) abort(); + \\ return 0; + \\} + , ""); + cases.add("ternary operator", \\#include \\static int cnt = 0;