aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2019-07-13 12:38:10 -0400
committerAndrew Kelley <andrew@ziglang.org>2019-07-13 12:38:10 -0400
commitc0489abcdbad82c95e332e5c7f9982b368a441f0 (patch)
tree18d0a3d00bb4dd0fb9b6a0cd07136d952632bb98 /src
parentbdfb31420a1046178406f40e867811de8d65d94a (diff)
downloadzig-c0489abcdbad82c95e332e5c7f9982b368a441f0.tar.gz
zig-c0489abcdbad82c95e332e5c7f9982b368a441f0.zip
translate-c: fix incorrectly translated double function pointer
closes #2887
Diffstat (limited to 'src')
-rw-r--r--src/translate_c.cpp25
1 files changed, 24 insertions, 1 deletions
diff --git a/src/translate_c.cpp b/src/translate_c.cpp
index 1487db0ff4..69c70958e5 100644
--- a/src/translate_c.cpp
+++ b/src/translate_c.cpp
@@ -833,6 +833,27 @@ static bool qual_type_has_wrapping_overflow(Context *c, ZigClangQualType qt) {
}
}
+static bool type_is_function(Context *c, const ZigClangType *ty, ZigClangSourceLocation source_loc) {
+ switch (ZigClangType_getTypeClass(ty)) {
+ case ZigClangType_FunctionProto:
+ case ZigClangType_FunctionNoProto:
+ return true;
+ case ZigClangType_Elaborated: {
+ const clang::ElaboratedType *elaborated_ty = reinterpret_cast<const clang::ElaboratedType*>(ty);
+ ZigClangQualType qt = bitcast(elaborated_ty->getNamedType());
+ return type_is_function(c, ZigClangQualType_getTypePtr(qt), source_loc);
+ }
+ case ZigClangType_Typedef: {
+ const ZigClangTypedefType *typedef_ty = reinterpret_cast<const ZigClangTypedefType*>(ty);
+ const ZigClangTypedefNameDecl *typedef_decl = ZigClangTypedefType_getDecl(typedef_ty);
+ ZigClangQualType underlying_type = ZigClangTypedefNameDecl_getUnderlyingType(typedef_decl);
+ return type_is_function(c, ZigClangQualType_getTypePtr(underlying_type), source_loc);
+ }
+ default:
+ return false;
+ }
+}
+
static bool type_is_opaque(Context *c, const ZigClangType *ty, ZigClangSourceLocation source_loc) {
switch (ZigClangType_getTypeClass(ty)) {
case ZigClangType_Builtin: {
@@ -1034,7 +1055,9 @@ static AstNode *trans_type(Context *c, const ZigClangType *ty, ZigClangSourceLoc
return trans_create_node_prefix_op(c, PrefixOpOptional, child_node);
}
- if (type_is_opaque(c, ZigClangQualType_getTypePtr(child_qt), source_loc)) {
+ if (type_is_function(c, ZigClangQualType_getTypePtr(child_qt), source_loc)) {
+ return trans_create_node_prefix_op(c, PrefixOpOptional, child_node);
+ } else if (type_is_opaque(c, ZigClangQualType_getTypePtr(child_qt), source_loc)) {
AstNode *pointer_node = trans_create_node_ptr_type(c,
ZigClangQualType_isConstQualified(child_qt),
ZigClangQualType_isVolatileQualified(child_qt),