| ... | ... | @@ -725,11 +725,15 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No |
| 725 | 725 | }; |
| 726 | 726 | |
| 727 | 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 | 732 | // TODO only emit this tag type if the enum tag type is not the default. |
| 730 | 733 | // I don't know what the default is, need to figure out how clang is deciding. |
| 731 | 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 | 737 | !isCBuiltinType(int_type, .Int)) |
| 734 | 738 | { |
| 735 | 739 | _ = try appendToken(c, .LParen, "("); |
| ... | ... | @@ -1555,8 +1559,7 @@ fn transCCast( |
| 1555 | 1559 | const elaborated_ty = @ptrCast(*const ZigClangElaboratedType, ZigClangQualType_getTypePtr(dst_type)); |
| 1556 | 1560 | return transCCast(rp, scope, loc, ZigClangElaboratedType_getNamedType(elaborated_ty), src_type, expr); |
| 1557 | 1561 | } |
| 1558 | | if (ZigClangQualType_getTypeClass(dst_type) == .Enum) |
| 1559 | | { |
| 1562 | if (ZigClangQualType_getTypeClass(dst_type) == .Enum) { |
| 1560 | 1563 | const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@intToEnum"); |
| 1561 | 1564 | try builtin_node.params.push(try transQualType(rp, dst_type, loc)); |
| 1562 | 1565 | _ = try appendToken(rp.c, .Comma, ","); |
| ... | ... | @@ -2145,7 +2148,7 @@ fn transCallExpr(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangCallExpr, |
| 2145 | 2148 | node.rtoken = try appendToken(rp.c, .RParen, ")"); |
| 2146 | 2149 | |
| 2147 | 2150 | if (fn_ty) |ty| { |
| 2148 | | const canon = ZigClangQualType_getCanonicalType(ZigClangFunctionProtoType_getReturnType(ty)); |
| 2151 | const canon = ZigClangQualType_getCanonicalType(ty.getReturnType()); |
| 2149 | 2152 | const ret_ty = ZigClangQualType_getTypePtr(canon); |
| 2150 | 2153 | if (ZigClangType_isVoidType(ret_ty)) { |
| 2151 | 2154 | _ = try appendToken(rp.c, .Semicolon, ";"); |
| ... | ... | @@ -2156,7 +2159,19 @@ fn transCallExpr(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangCallExpr, |
| 2156 | 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 | 2175 | const canon = ZigClangQualType_getCanonicalType(qt); |
| 2161 | 2176 | var ty = ZigClangQualType_getTypePtr(canon); |
| 2162 | 2177 | is_ptr.* = false; |
| ... | ... | @@ -2167,7 +2182,10 @@ fn qualTypeGetFnProto(qt: ZigClangQualType, is_ptr: *bool) ?*const ZigClangFunct |
| 2167 | 2182 | ty = ZigClangQualType_getTypePtr(child_qt); |
| 2168 | 2183 | } |
| 2169 | 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 | 2190 | return null; |
| 2173 | 2191 | } |
| ... | ... | @@ -2771,7 +2789,10 @@ fn qualTypeChildIsFnProto(qt: ZigClangQualType) bool { |
| 2771 | 2789 | .Paren => { |
| 2772 | 2790 | const paren_type = @ptrCast(*const ZigClangParenType, ty); |
| 2773 | 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 | 2797 | .Attributed => { |
| 2777 | 2798 | const attr_type = @ptrCast(*const ZigClangAttributedType, ty); |
| ... | ... | @@ -3571,11 +3592,16 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour |
| 3571 | 3592 | else => return revertAndWarn(rp, error.UnsupportedType, source_loc, "unsupported builtin type", .{}), |
| 3572 | 3593 | }); |
| 3573 | 3594 | }, |
| 3574 | | .FunctionProto, .FunctionNoProto => { |
| 3595 | .FunctionProto => { |
| 3575 | 3596 | const fn_proto_ty = @ptrCast(*const ZigClangFunctionProtoType, ty); |
| 3576 | 3597 | const fn_proto = try transFnProto(rp, null, fn_proto_ty, source_loc, null, false); |
| 3577 | 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 | 3605 | .Paren => { |
| 3580 | 3606 | const paren_ty = @ptrCast(*const ZigClangParenType, ty); |
| 3581 | 3607 | return transQualType(rp, ZigClangParenType_getInnerType(paren_ty), source_loc); |