authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-01-30 23:16:52+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-01-30 21:33:50-05:00
log176bc53858053866e2a751e8d1e2a6a52871cff0
treee3801aac9b0a3ec750efef50f5aab12e4b275095
parent1e78070a40bac709bfd25beb24c1721d4977a69d

translate-c: Fix translation of fn pointers

Closes #4332

2 files changed, 21 insertions(+), 22 deletions(-)

src-self-hosted/translate_c.zig+1-22
......@@ -3446,31 +3446,10 @@ fn qualTypeToLog2IntRef(rp: RestorePoint, qt: ZigClangQualType, source_loc: ZigC
34463446}
34473447
34483448fn qualTypeChildIsFnProto(qt: ZigClangQualType) bool {
3449 const ty = ZigClangQualType_getTypePtr(qt);
3449 const ty = qualTypeCanon(qt);
34503450
34513451 switch (ZigClangType_getTypeClass(ty)) {
34523452 .FunctionProto, .FunctionNoProto => return true,
3453 .Elaborated => {
3454 const elaborated_ty = @ptrCast(*const ZigClangElaboratedType, ty);
3455 return qualTypeChildIsFnProto(ZigClangElaboratedType_getNamedType(elaborated_ty));
3456 },
3457 .Typedef => {
3458 const typedef_ty = @ptrCast(*const ZigClangTypedefType, ty);
3459 const typedef_decl = ZigClangTypedefType_getDecl(typedef_ty);
3460 return qualTypeChildIsFnProto(ZigClangTypedefNameDecl_getUnderlyingType(typedef_decl));
3461 },
3462 .Paren => {
3463 const paren_type = @ptrCast(*const ZigClangParenType, ty);
3464 const inner_type = ZigClangParenType_getInnerType(paren_type);
3465 switch (ZigClangQualType_getTypeClass(inner_type)) {
3466 .FunctionProto, .FunctionNoProto => return true,
3467 else => return false,
3468 }
3469 },
3470 .Attributed => {
3471 const attr_type = @ptrCast(*const ZigClangAttributedType, ty);
3472 return qualTypeChildIsFnProto(ZigClangAttributedType_getEquivalentType(attr_type));
3473 },
34743453 else => return false,
34753454 }
34763455}
test/translate_c.zig+20
......@@ -3,6 +3,26 @@ const builtin = @import("builtin");
33const Target = @import("std").Target;
44
55pub fn addCases(cases: *tests.TranslateCContext) void {
6 cases.add("function prototype translated as optional",
7 \\typedef void (*fnptr_ty)(void);
8 \\typedef __attribute__((cdecl)) void (*fnptr_attr_ty)(void);
9 \\struct foo {
10 \\ __attribute__((cdecl)) void (*foo)(void);
11 \\ void (*bar)(void);
12 \\ fnptr_ty baz;
13 \\ fnptr_attr_ty qux;
14 \\};
15 , &[_][]const u8{
16 \\pub const fnptr_ty = ?fn () callconv(.C) void;
17 \\pub const fnptr_attr_ty = ?fn () callconv(.C) void;
18 \\pub const struct_foo = extern struct {
19 \\ foo: ?fn () callconv(.C) void,
20 \\ bar: ?fn () callconv(.C) void,
21 \\ baz: fnptr_ty,
22 \\ qux: fnptr_attr_ty,
23 \\};
24 });
25
626 cases.add("function prototype with parenthesis",
727 \\void (f0) (void *L);
828 \\void ((f1)) (void *L);