| ... | ... | @@ -2082,13 +2082,20 @@ fn transCCast( |
| 2082 | 2082 | // 3. Bit-cast to correct signed-ness |
| 2083 | 2083 | const src_type_is_signed = cIsSignedInteger(src_type) or cIsEnum(src_type); |
| 2084 | 2084 | const src_int_type = if (cIsInteger(src_type)) src_type else cIntTypeForEnum(src_type); |
| 2085 | | const src_int_expr = if (cIsInteger(src_type)) expr else try transEnumToInt(rp.c, expr); |
| 2085 | var src_int_expr = if (cIsInteger(src_type)) expr else try transEnumToInt(rp.c, expr); |
| 2086 | 2086 | |
| 2087 | 2087 | // @bitCast(dest_type, intermediate_value) |
| 2088 | 2088 | const cast_node = try rp.c.createBuiltinCall("@bitCast", 2); |
| 2089 | 2089 | cast_node.params()[0] = try transQualType(rp, dst_type, loc); |
| 2090 | 2090 | _ = try appendToken(rp.c, .Comma, ","); |
| 2091 | 2091 | |
| 2092 | if (isBoolRes(src_int_expr)) { |
| 2093 | const bool_to_int_node = try rp.c.createBuiltinCall("@boolToInt", 1); |
| 2094 | bool_to_int_node.params()[0] = src_int_expr; |
| 2095 | bool_to_int_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 2096 | src_int_expr = &bool_to_int_node.base; |
| 2097 | } |
| 2098 | |
| 2092 | 2099 | switch (cIntTypeCmp(dst_type, src_int_type)) { |
| 2093 | 2100 | .lt => { |
| 2094 | 2101 | // @truncate(SameSignSmallerInt, src_int_expr) |
| ... | ... | @@ -3113,7 +3120,26 @@ fn transCallExpr(rp: RestorePoint, scope: *Scope, stmt: *const clang.CallExpr, r |
| 3113 | 3120 | if (i != 0) { |
| 3114 | 3121 | _ = try appendToken(rp.c, .Comma, ","); |
| 3115 | 3122 | } |
| 3116 | | call_params[i] = try transExpr(rp, scope, args[i], .used, .r_value); |
| 3123 | var call_param = try transExpr(rp, scope, args[i], .used, .r_value); |
| 3124 | |
| 3125 | // In C the result type of a boolean expression is int. If this result is passed as |
| 3126 | // an argument to a function whose parameter is also int, there is no cast. Therefore |
| 3127 | // in Zig we'll need to cast it from bool to u1 (which will safely coerce to c_int). |
| 3128 | if (fn_ty) |ty| { |
| 3129 | switch (ty) { |
| 3130 | .Proto => |fn_proto| { |
| 3131 | const param_qt = fn_proto.getParamType(@intCast(c_uint, i)); |
| 3132 | if (isBoolRes(call_param) and cIsNativeInt(param_qt)) { |
| 3133 | const builtin_node = try rp.c.createBuiltinCall("@boolToInt", 1); |
| 3134 | builtin_node.params()[0] = call_param; |
| 3135 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 3136 | call_param = &builtin_node.base; |
| 3137 | } |
| 3138 | }, |
| 3139 | else => {}, |
| 3140 | } |
| 3141 | } |
| 3142 | call_params[i] = call_param; |
| 3117 | 3143 | } |
| 3118 | 3144 | node.rtoken = try appendToken(rp.c, .RParen, ")"); |
| 3119 | 3145 | |
| ... | ... | @@ -4125,6 +4151,13 @@ fn cIsSignedInteger(qt: clang.QualType) bool { |
| 4125 | 4151 | }; |
| 4126 | 4152 | } |
| 4127 | 4153 | |
| 4154 | fn cIsNativeInt(qt: clang.QualType) bool { |
| 4155 | const c_type = qualTypeCanon(qt); |
| 4156 | if (c_type.getTypeClass() != .Builtin) return false; |
| 4157 | const builtin_ty = @ptrCast(*const clang.BuiltinType, c_type); |
| 4158 | return builtin_ty.getKind() == .Int; |
| 4159 | } |
| 4160 | |
| 4128 | 4161 | fn cIsFloating(qt: clang.QualType) bool { |
| 4129 | 4162 | const c_type = qualTypeCanon(qt); |
| 4130 | 4163 | if (c_type.getTypeClass() != .Builtin) return false; |