diff options
Diffstat (limited to 'src/translate_c.cpp')
| -rw-r--r-- | src/translate_c.cpp | 44 |
1 files changed, 41 insertions, 3 deletions
diff --git a/src/translate_c.cpp b/src/translate_c.cpp index 28e4a7daa4..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: { @@ -840,8 +861,23 @@ static bool type_is_opaque(Context *c, const ZigClangType *ty, ZigClangSourceLoc return ZigClangBuiltinType_getKind(builtin_ty) == ZigClangBuiltinTypeVoid; } case ZigClangType_Record: { - const clang::RecordType *record_ty = reinterpret_cast<const clang::RecordType*>(ty); - return record_ty->getDecl()->getDefinition() == nullptr; + const ZigClangRecordType *record_ty = reinterpret_cast<const ZigClangRecordType*>(ty); + const ZigClangRecordDecl *record_decl = ZigClangRecordType_getDecl(record_ty); + const ZigClangRecordDecl *record_def = ZigClangRecordDecl_getDefinition(record_decl); + if (record_def == nullptr) { + return true; + } + for (auto it = reinterpret_cast<const clang::RecordDecl *>(record_def)->field_begin(), + it_end = reinterpret_cast<const clang::RecordDecl *>(record_def)->field_end(); + it != it_end; ++it) + { + const clang::FieldDecl *field_decl = *it; + + if (field_decl->isBitField()) { + return true; + } + } + return false; } case ZigClangType_Elaborated: { const clang::ElaboratedType *elaborated_ty = reinterpret_cast<const clang::ElaboratedType*>(ty); @@ -1019,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), |
