| ... | @@ -725,11 +725,15 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No | ... | @@ -725,11 +725,15 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No |
| 725 | }; | 725 | }; |
| 726 | | 726 | |
| 727 | const int_type = ZigClangEnumDecl_getIntegerType(enum_decl); | 727 | const int_type = ZigClangEnumDecl_getIntegerType(enum_decl); |
| | 728 | // The underlying type may be null in case of forward-declared enum |
| | 729 | // types, while that's not ISO-C compliant many compilers allow this and |
| | 730 | // default to the usual integer type used for all the enums. |
| 728 | | 731 | |
| 729 | // TODO only emit this tag type if the enum tag type is not the default. | 732 | // TODO only emit this tag type if the enum tag type is not the default. |
| 730 | // I don't know what the default is, need to figure out how clang is deciding. | 733 | // I don't know what the default is, need to figure out how clang is deciding. |
| 731 | // it appears to at least be different across gcc/msvc | 734 | // it appears to at least be different across gcc/msvc |
| 732 | if (!isCBuiltinType(int_type, .UInt) and | 735 | if (int_type.ptr != null and |
| | 736 | !isCBuiltinType(int_type, .UInt) and |
| 733 | !isCBuiltinType(int_type, .Int)) | 737 | !isCBuiltinType(int_type, .Int)) |
| 734 | { | 738 | { |
| 735 | _ = try appendToken(c, .LParen, "("); | 739 | _ = try appendToken(c, .LParen, "("); |
| ... | @@ -1555,8 +1559,7 @@ fn transCCast( | ... | @@ -1555,8 +1559,7 @@ fn transCCast( |
| 1555 | const elaborated_ty = @ptrCast(*const ZigClangElaboratedType, ZigClangQualType_getTypePtr(dst_type)); | 1559 | const elaborated_ty = @ptrCast(*const ZigClangElaboratedType, ZigClangQualType_getTypePtr(dst_type)); |
| 1556 | return transCCast(rp, scope, loc, ZigClangElaboratedType_getNamedType(elaborated_ty), src_type, expr); | 1560 | return transCCast(rp, scope, loc, ZigClangElaboratedType_getNamedType(elaborated_ty), src_type, expr); |
| 1557 | } | 1561 | } |
| 1558 | if (ZigClangQualType_getTypeClass(dst_type) == .Enum) | 1562 | if (ZigClangQualType_getTypeClass(dst_type) == .Enum) { |
| 1559 | { | | |
| 1560 | const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@intToEnum"); | 1563 | const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@intToEnum"); |
| 1561 | try builtin_node.params.push(try transQualType(rp, dst_type, loc)); | 1564 | try builtin_node.params.push(try transQualType(rp, dst_type, loc)); |
| 1562 | _ = try appendToken(rp.c, .Comma, ","); | 1565 | _ = try appendToken(rp.c, .Comma, ","); |
| ... | @@ -2145,7 +2148,7 @@ fn transCallExpr(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangCallExpr, | ... | @@ -2145,7 +2148,7 @@ fn transCallExpr(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangCallExpr, |
| 2145 | node.rtoken = try appendToken(rp.c, .RParen, ")"); | 2148 | node.rtoken = try appendToken(rp.c, .RParen, ")"); |
| 2146 | | 2149 | |
| 2147 | if (fn_ty) |ty| { | 2150 | if (fn_ty) |ty| { |
| 2148 | const canon = ZigClangQualType_getCanonicalType(ZigClangFunctionProtoType_getReturnType(ty)); | 2151 | const canon = ZigClangQualType_getCanonicalType(ty.getReturnType()); |
| 2149 | const ret_ty = ZigClangQualType_getTypePtr(canon); | 2152 | const ret_ty = ZigClangQualType_getTypePtr(canon); |
| 2150 | if (ZigClangType_isVoidType(ret_ty)) { | 2153 | if (ZigClangType_isVoidType(ret_ty)) { |
| 2151 | _ = try appendToken(rp.c, .Semicolon, ";"); | 2154 | _ = try appendToken(rp.c, .Semicolon, ";"); |
| ... | @@ -2156,7 +2159,19 @@ fn transCallExpr(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangCallExpr, | ... | @@ -2156,7 +2159,19 @@ fn transCallExpr(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangCallExpr, |
| 2156 | return maybeSuppressResult(rp, scope, result_used, &node.base); | 2159 | return maybeSuppressResult(rp, scope, result_used, &node.base); |
| 2157 | } | 2160 | } |
| 2158 | | 2161 | |
| 2159 | fn qualTypeGetFnProto(qt: ZigClangQualType, is_ptr: *bool) ?*const ZigClangFunctionProtoType { | 2162 | const ClangFunctionType = union(enum) { |
| | 2163 | Proto: *const ZigClangFunctionProtoType, |
| | 2164 | NoProto: *const ZigClangFunctionType, |
| | 2165 | |
| | 2166 | fn getReturnType(self: @This()) ZigClangQualType { |
| | 2167 | switch (@as(@TagType(@This()), self)) { |
| | 2168 | .Proto => return ZigClangFunctionProtoType_getReturnType(self.Proto), |
| | 2169 | .NoProto => return ZigClangFunctionType_getReturnType(self.NoProto), |
| | 2170 | } |
| | 2171 | } |
| | 2172 | }; |
| | 2173 | |
| | 2174 | fn qualTypeGetFnProto(qt: ZigClangQualType, is_ptr: *bool) ?ClangFunctionType { |
| 2160 | const canon = ZigClangQualType_getCanonicalType(qt); | 2175 | const canon = ZigClangQualType_getCanonicalType(qt); |
| 2161 | var ty = ZigClangQualType_getTypePtr(canon); | 2176 | var ty = ZigClangQualType_getTypePtr(canon); |
| 2162 | is_ptr.* = false; | 2177 | is_ptr.* = false; |
| ... | @@ -2167,7 +2182,10 @@ fn qualTypeGetFnProto(qt: ZigClangQualType, is_ptr: *bool) ?*const ZigClangFunct | ... | @@ -2167,7 +2182,10 @@ fn qualTypeGetFnProto(qt: ZigClangQualType, is_ptr: *bool) ?*const ZigClangFunct |
| 2167 | ty = ZigClangQualType_getTypePtr(child_qt); | 2182 | ty = ZigClangQualType_getTypePtr(child_qt); |
| 2168 | } | 2183 | } |
| 2169 | if (ZigClangType_getTypeClass(ty) == .FunctionProto) { | 2184 | if (ZigClangType_getTypeClass(ty) == .FunctionProto) { |
| 2170 | return @ptrCast(*const ZigClangFunctionProtoType, ty); | 2185 | return ClangFunctionType{ .Proto = @ptrCast(*const ZigClangFunctionProtoType, ty) }; |
| | 2186 | } |
| | 2187 | if (ZigClangType_getTypeClass(ty) == .FunctionNoProto) { |
| | 2188 | return ClangFunctionType{ .NoProto = @ptrCast(*const ZigClangFunctionType, ty) }; |
| 2171 | } | 2189 | } |
| 2172 | return null; | 2190 | return null; |
| 2173 | } | 2191 | } |
| ... | @@ -2771,7 +2789,10 @@ fn qualTypeChildIsFnProto(qt: ZigClangQualType) bool { | ... | @@ -2771,7 +2789,10 @@ fn qualTypeChildIsFnProto(qt: ZigClangQualType) bool { |
| 2771 | .Paren => { | 2789 | .Paren => { |
| 2772 | const paren_type = @ptrCast(*const ZigClangParenType, ty); | 2790 | const paren_type = @ptrCast(*const ZigClangParenType, ty); |
| 2773 | const inner_type = ZigClangParenType_getInnerType(paren_type); | 2791 | const inner_type = ZigClangParenType_getInnerType(paren_type); |
| 2774 | return ZigClangQualType_getTypeClass(inner_type) == .FunctionProto; | 2792 | switch (ZigClangQualType_getTypeClass(inner_type)) { |
| | 2793 | .FunctionProto, .FunctionNoProto => return true, |
| | 2794 | else => return false, |
| | 2795 | } |
| 2775 | }, | 2796 | }, |
| 2776 | .Attributed => { | 2797 | .Attributed => { |
| 2777 | const attr_type = @ptrCast(*const ZigClangAttributedType, ty); | 2798 | const attr_type = @ptrCast(*const ZigClangAttributedType, ty); |
| ... | @@ -3571,11 +3592,16 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour | ... | @@ -3571,11 +3592,16 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour |
| 3571 | else => return revertAndWarn(rp, error.UnsupportedType, source_loc, "unsupported builtin type", .{}), | 3592 | else => return revertAndWarn(rp, error.UnsupportedType, source_loc, "unsupported builtin type", .{}), |
| 3572 | }); | 3593 | }); |
| 3573 | }, | 3594 | }, |
| 3574 | .FunctionProto, .FunctionNoProto => { | 3595 | .FunctionProto => { |
| 3575 | const fn_proto_ty = @ptrCast(*const ZigClangFunctionProtoType, ty); | 3596 | const fn_proto_ty = @ptrCast(*const ZigClangFunctionProtoType, ty); |
| 3576 | const fn_proto = try transFnProto(rp, null, fn_proto_ty, source_loc, null, false); | 3597 | const fn_proto = try transFnProto(rp, null, fn_proto_ty, source_loc, null, false); |
| 3577 | return &fn_proto.base; | 3598 | return &fn_proto.base; |
| 3578 | }, | 3599 | }, |
| | 3600 | .FunctionNoProto => { |
| | 3601 | const fn_no_proto_ty = @ptrCast(*const ZigClangFunctionType, ty); |
| | 3602 | const fn_proto = try transFnNoProto(rp, fn_no_proto_ty, source_loc, null, false); |
| | 3603 | return &fn_proto.base; |
| | 3604 | }, |
| 3579 | .Paren => { | 3605 | .Paren => { |
| 3580 | const paren_ty = @ptrCast(*const ZigClangParenType, ty); | 3606 | const paren_ty = @ptrCast(*const ZigClangParenType, ty); |
| 3581 | return transQualType(rp, ZigClangParenType_getInnerType(paren_ty), source_loc); | 3607 | return transQualType(rp, ZigClangParenType_getInnerType(paren_ty), source_loc); |