diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index 0c186b40f4..ec89072ca4 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -3446,31 +3446,10 @@ fn qualTypeToLog2IntRef(rp: RestorePoint, qt: ZigClangQualType, source_loc: ZigC } fn qualTypeChildIsFnProto(qt: ZigClangQualType) bool { - const ty = ZigClangQualType_getTypePtr(qt); + const ty = qualTypeCanon(qt); switch (ZigClangType_getTypeClass(ty)) { .FunctionProto, .FunctionNoProto => return true, - .Elaborated => { - const elaborated_ty = @ptrCast(*const ZigClangElaboratedType, ty); - return qualTypeChildIsFnProto(ZigClangElaboratedType_getNamedType(elaborated_ty)); - }, - .Typedef => { - const typedef_ty = @ptrCast(*const ZigClangTypedefType, ty); - const typedef_decl = ZigClangTypedefType_getDecl(typedef_ty); - return qualTypeChildIsFnProto(ZigClangTypedefNameDecl_getUnderlyingType(typedef_decl)); - }, - .Paren => { - const paren_type = @ptrCast(*const ZigClangParenType, ty); - const inner_type = ZigClangParenType_getInnerType(paren_type); - switch (ZigClangQualType_getTypeClass(inner_type)) { - .FunctionProto, .FunctionNoProto => return true, - else => return false, - } - }, - .Attributed => { - const attr_type = @ptrCast(*const ZigClangAttributedType, ty); - return qualTypeChildIsFnProto(ZigClangAttributedType_getEquivalentType(attr_type)); - }, else => return false, } } diff --git a/test/translate_c.zig b/test/translate_c.zig index be4ea8083b..22467b1e65 100644 --- a/test/translate_c.zig +++ b/test/translate_c.zig @@ -3,6 +3,26 @@ const builtin = @import("builtin"); const Target = @import("std").Target; pub fn addCases(cases: *tests.TranslateCContext) void { + cases.add("function prototype translated as optional", + \\typedef void (*fnptr_ty)(void); + \\typedef __attribute__((cdecl)) void (*fnptr_attr_ty)(void); + \\struct foo { + \\ __attribute__((cdecl)) void (*foo)(void); + \\ void (*bar)(void); + \\ fnptr_ty baz; + \\ fnptr_attr_ty qux; + \\}; + , &[_][]const u8{ + \\pub const fnptr_ty = ?fn () callconv(.C) void; + \\pub const fnptr_attr_ty = ?fn () callconv(.C) void; + \\pub const struct_foo = extern struct { + \\ foo: ?fn () callconv(.C) void, + \\ bar: ?fn () callconv(.C) void, + \\ baz: fnptr_ty, + \\ qux: fnptr_attr_ty, + \\}; + }); + cases.add("function prototype with parenthesis", \\void (f0) (void *L); \\void ((f1)) (void *L);