authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-07-13 12:38:10-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-07-13 12:38:10-04:00
logc0489abcdbad82c95e332e5c7f9982b368a441f0
tree18d0a3d00bb4dd0fb9b6a0cd07136d952632bb98
parentbdfb31420a1046178406f40e867811de8d65d94a
signaturelock-open Commit is signed but in an unrecognized format.

translate-c: fix incorrectly translated double function pointer

closes #2887

2 files changed, 38 insertions(+), 1 deletions(-)

src/translate_c.cpp+24-1
...@@ -833,6 +833,27 @@ static bool qual_type_has_wrapping_overflow(Context *c, ZigClangQualType qt) {...@@ -833,6 +833,27 @@ static bool qual_type_has_wrapping_overflow(Context *c, ZigClangQualType qt) {
833 }833 }
834}834}
835835
836static bool type_is_function(Context *c, const ZigClangType *ty, ZigClangSourceLocation source_loc) {
837 switch (ZigClangType_getTypeClass(ty)) {
838 case ZigClangType_FunctionProto:
839 case ZigClangType_FunctionNoProto:
840 return true;
841 case ZigClangType_Elaborated: {
842 const clang::ElaboratedType *elaborated_ty = reinterpret_cast<const clang::ElaboratedType*>(ty);
843 ZigClangQualType qt = bitcast(elaborated_ty->getNamedType());
844 return type_is_function(c, ZigClangQualType_getTypePtr(qt), source_loc);
845 }
846 case ZigClangType_Typedef: {
847 const ZigClangTypedefType *typedef_ty = reinterpret_cast<const ZigClangTypedefType*>(ty);
848 const ZigClangTypedefNameDecl *typedef_decl = ZigClangTypedefType_getDecl(typedef_ty);
849 ZigClangQualType underlying_type = ZigClangTypedefNameDecl_getUnderlyingType(typedef_decl);
850 return type_is_function(c, ZigClangQualType_getTypePtr(underlying_type), source_loc);
851 }
852 default:
853 return false;
854 }
855}
856
836static bool type_is_opaque(Context *c, const ZigClangType *ty, ZigClangSourceLocation source_loc) {857static bool type_is_opaque(Context *c, const ZigClangType *ty, ZigClangSourceLocation source_loc) {
837 switch (ZigClangType_getTypeClass(ty)) {858 switch (ZigClangType_getTypeClass(ty)) {
838 case ZigClangType_Builtin: {859 case ZigClangType_Builtin: {
...@@ -1034,7 +1055,9 @@ static AstNode *trans_type(Context *c, const ZigClangType *ty, ZigClangSourceLoc...@@ -1034,7 +1055,9 @@ static AstNode *trans_type(Context *c, const ZigClangType *ty, ZigClangSourceLoc
1034 return trans_create_node_prefix_op(c, PrefixOpOptional, child_node);1055 return trans_create_node_prefix_op(c, PrefixOpOptional, child_node);
1035 }1056 }
10361057
1037 if (type_is_opaque(c, ZigClangQualType_getTypePtr(child_qt), source_loc)) {1058 if (type_is_function(c, ZigClangQualType_getTypePtr(child_qt), source_loc)) {
1059 return trans_create_node_prefix_op(c, PrefixOpOptional, child_node);
1060 } else if (type_is_opaque(c, ZigClangQualType_getTypePtr(child_qt), source_loc)) {
1038 AstNode *pointer_node = trans_create_node_ptr_type(c,1061 AstNode *pointer_node = trans_create_node_ptr_type(c,
1039 ZigClangQualType_isConstQualified(child_qt),1062 ZigClangQualType_isConstQualified(child_qt),
1040 ZigClangQualType_isVolatileQualified(child_qt),1063 ZigClangQualType_isVolatileQualified(child_qt),
test/translate_c.zig+14
...@@ -40,6 +40,20 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -40,6 +40,20 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
40 );40 );
4141
42 /////////////// Cases for only stage1 which are TODO items for stage2 ////////////////42 /////////////// Cases for only stage1 which are TODO items for stage2 ////////////////
43 cases.add("typedef of function in struct field",
44 \\typedef void lws_callback_function(void);
45 \\struct Foo {
46 \\ void (*func)(void);
47 \\ lws_callback_function *callback_http;
48 \\};
49 ,
50 \\pub const lws_callback_function = extern fn() void;
51 \\pub const struct_Foo = extern struct {
52 \\ func: ?extern fn() void,
53 \\ callback_http: ?lws_callback_function,
54 \\};
55 );
56
43 cases.add("pointer to struct demoted to opaque due to bit fields",57 cases.add("pointer to struct demoted to opaque due to bit fields",
44 \\struct Foo {58 \\struct Foo {
45 \\ unsigned int: 1;59 \\ unsigned int: 1;