| author | |
| committer | |
| log | 176bc53858053866e2a751e8d1e2a6a52871cff0 |
| tree | e3801aac9b0a3ec750efef50f5aab12e4b275095 |
| parent | 1e78070a40bac709bfd25beb24c1721d4977a69d |
Closes #43322 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 |
| 3446 | 3446 | } |
| 3447 | 3447 | |
| 3448 | 3448 | fn qualTypeChildIsFnProto(qt: ZigClangQualType) bool { |
| 3449 | const ty = ZigClangQualType_getTypePtr(qt); | |
| 3449 | const ty = qualTypeCanon(qt); | |
| 3450 | 3450 | |
| 3451 | 3451 | switch (ZigClangType_getTypeClass(ty)) { |
| 3452 | 3452 | .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 | }, | |
| 3474 | 3453 | else => return false, |
| 3475 | 3454 | } |
| 3476 | 3455 | } |
test/translate_c.zig+20| ... | ... | @@ -3,6 +3,26 @@ const builtin = @import("builtin"); |
| 3 | 3 | const Target = @import("std").Target; |
| 4 | 4 | |
| 5 | 5 | pub 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 | ||
| 6 | 26 | cases.add("function prototype with parenthesis", |
| 7 | 27 | \\void (f0) (void *L); |
| 8 | 28 | \\void ((f1)) (void *L); |