| ... | @@ -1285,7 +1285,7 @@ fn transDeclStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangDeclStmt) | ... | @@ -1285,7 +1285,7 @@ fn transDeclStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangDeclStmt) |
| 1285 | try transExprCoercing(rp, scope, expr, .used, .r_value) | 1285 | try transExprCoercing(rp, scope, expr, .used, .r_value) |
| 1286 | else | 1286 | else |
| 1287 | try transCreateNodeUndefinedLiteral(c); | 1287 | try transCreateNodeUndefinedLiteral(c); |
| 1288 | if (isBoolRes(init_node)) { | 1288 | if (!qualTypeIsBoolean(qual_type) and isBoolRes(init_node)) { |
| 1289 | const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt"); | 1289 | const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt"); |
| 1290 | try builtin_node.params.push(init_node); | 1290 | try builtin_node.params.push(init_node); |
| 1291 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | 1291 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| ... | @@ -1351,9 +1351,13 @@ fn transImplicitCastExpr( | ... | @@ -1351,9 +1351,13 @@ fn transImplicitCastExpr( |
| 1351 | return transCreateNodeInfixOp(rp, scope, &ptr_to_int.base, .BangEqual, op_token, rhs_node, result_used, false); | 1351 | return transCreateNodeInfixOp(rp, scope, &ptr_to_int.base, .BangEqual, op_token, rhs_node, result_used, false); |
| 1352 | }, | 1352 | }, |
| 1353 | .IntegralToBoolean => { | 1353 | .IntegralToBoolean => { |
| 1354 | // val != 0 | | |
| 1355 | const node = try transExpr(rp, scope, sub_expr, .used, .r_value); | 1354 | const node = try transExpr(rp, scope, sub_expr, .used, .r_value); |
| 1356 | | 1355 | |
| | 1356 | // The expression is already a boolean one, return it as-is |
| | 1357 | if (isBoolRes(node)) |
| | 1358 | return node; |
| | 1359 | |
| | 1360 | // val != 0 |
| 1357 | const op_token = try appendToken(rp.c, .BangEqual, "!="); | 1361 | const op_token = try appendToken(rp.c, .BangEqual, "!="); |
| 1358 | const rhs_node = try transCreateNodeInt(rp.c, 0); | 1362 | const rhs_node = try transCreateNodeInt(rp.c, 0); |
| 1359 | return transCreateNodeInfixOp(rp, scope, node, .BangEqual, op_token, rhs_node, result_used, false); | 1363 | return transCreateNodeInfixOp(rp, scope, node, .BangEqual, op_token, rhs_node, result_used, false); |
| ... | @@ -1409,6 +1413,10 @@ fn transBoolExpr( | ... | @@ -1409,6 +1413,10 @@ fn transBoolExpr( |
| 1409 | } | 1413 | } |
| 1410 | } | 1414 | } |
| 1411 | | 1415 | |
| | 1416 | fn exprIsBooleanType(expr: *const ZigClangExpr) bool { |
| | 1417 | return qualTypeIsBoolean(ZigClangExpr_getType(expr)); |
| | 1418 | } |
| | 1419 | |
| 1412 | fn isBoolRes(res: *ast.Node) bool { | 1420 | fn isBoolRes(res: *ast.Node) bool { |
| 1413 | switch (res.id) { | 1421 | switch (res.id) { |
| 1414 | .InfixOp => switch (@fieldParentPtr(ast.Node.InfixOp, "base", res).op) { | 1422 | .InfixOp => switch (@fieldParentPtr(ast.Node.InfixOp, "base", res).op) { |
| ... | @@ -1738,6 +1746,14 @@ fn transCCast( | ... | @@ -1738,6 +1746,14 @@ fn transCCast( |
| 1738 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | 1746 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 1739 | return &builtin_node.base; | 1747 | return &builtin_node.base; |
| 1740 | } | 1748 | } |
| | 1749 | if (ZigClangType_isBooleanType(qualTypeCanon(src_type)) and |
| | 1750 | !ZigClangType_isBooleanType(qualTypeCanon(dst_type))) |
| | 1751 | { |
| | 1752 | const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt"); |
| | 1753 | try builtin_node.params.push(expr); |
| | 1754 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| | 1755 | return &builtin_node.base; |
| | 1756 | } |
| 1741 | if (ZigClangQualType_getTypeClass(ZigClangQualType_getCanonicalType(dst_type)) == .Enum) { | 1757 | if (ZigClangQualType_getTypeClass(ZigClangQualType_getCanonicalType(dst_type)) == .Enum) { |
| 1742 | const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@intToEnum"); | 1758 | const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@intToEnum"); |
| 1743 | try builtin_node.params.push(try transQualType(rp, dst_type, loc)); | 1759 | try builtin_node.params.push(try transQualType(rp, dst_type, loc)); |
| ... | @@ -3089,6 +3105,10 @@ fn qualTypeIsPtr(qt: ZigClangQualType) bool { | ... | @@ -3089,6 +3105,10 @@ fn qualTypeIsPtr(qt: ZigClangQualType) bool { |
| 3089 | return ZigClangType_getTypeClass(qualTypeCanon(qt)) == .Pointer; | 3105 | return ZigClangType_getTypeClass(qualTypeCanon(qt)) == .Pointer; |
| 3090 | } | 3106 | } |
| 3091 | | 3107 | |
| | 3108 | fn qualTypeIsBoolean(qt: ZigClangQualType) bool { |
| | 3109 | return ZigClangType_isBooleanType(qualTypeCanon(qt)); |
| | 3110 | } |
| | 3111 | |
| 3092 | fn qualTypeIntBitWidth(rp: RestorePoint, qt: ZigClangQualType, source_loc: ZigClangSourceLocation) !u32 { | 3112 | fn qualTypeIntBitWidth(rp: RestorePoint, qt: ZigClangQualType, source_loc: ZigClangSourceLocation) !u32 { |
| 3093 | const ty = ZigClangQualType_getTypePtr(qt); | 3113 | const ty = ZigClangQualType_getTypePtr(qt); |
| 3094 | | 3114 | |
| ... | @@ -3365,7 +3385,7 @@ fn transCreateNodeAssign( | ... | @@ -3365,7 +3385,7 @@ fn transCreateNodeAssign( |
| 3365 | const lhs_node = try transExpr(rp, scope, lhs, .used, .l_value); | 3385 | const lhs_node = try transExpr(rp, scope, lhs, .used, .l_value); |
| 3366 | const eq_token = try appendToken(rp.c, .Equal, "="); | 3386 | const eq_token = try appendToken(rp.c, .Equal, "="); |
| 3367 | var rhs_node = try transExprCoercing(rp, scope, rhs, .used, .r_value); | 3387 | var rhs_node = try transExprCoercing(rp, scope, rhs, .used, .r_value); |
| 3368 | if (isBoolRes(rhs_node)) { | 3388 | if (!exprIsBooleanType(lhs) and isBoolRes(rhs_node)) { |
| 3369 | const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt"); | 3389 | const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt"); |
| 3370 | try builtin_node.params.push(rhs_node); | 3390 | try builtin_node.params.push(rhs_node); |
| 3371 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | 3391 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| ... | @@ -3390,7 +3410,7 @@ fn transCreateNodeAssign( | ... | @@ -3390,7 +3410,7 @@ fn transCreateNodeAssign( |
| 3390 | const node = try transCreateNodeVarDecl(rp.c, false, true, tmp); | 3410 | const node = try transCreateNodeVarDecl(rp.c, false, true, tmp); |
| 3391 | node.eq_token = try appendToken(rp.c, .Equal, "="); | 3411 | node.eq_token = try appendToken(rp.c, .Equal, "="); |
| 3392 | var rhs_node = try transExpr(rp, &block_scope.base, rhs, .used, .r_value); | 3412 | var rhs_node = try transExpr(rp, &block_scope.base, rhs, .used, .r_value); |
| 3393 | if (isBoolRes(rhs_node)) { | 3413 | if (!exprIsBooleanType(lhs) and isBoolRes(rhs_node)) { |
| 3394 | const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt"); | 3414 | const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt"); |
| 3395 | try builtin_node.params.push(rhs_node); | 3415 | try builtin_node.params.push(rhs_node); |
| 3396 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | 3416 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |