@@ -965,12 +965,8 @@ bool Converter::VisitReturnStmt(clang::ReturnStmt *stmt) {
965965}
966966
967967void Converter::ConvertCondition (clang::Expr *cond) {
968- if (!cond->getType ()->isBooleanType ()) {
969- PushExprKind push (*this , ExprKind::RValue);
970- Convert (CreateConversionToBool (cond, ctx_));
971- return ;
972- }
973- Convert (cond);
968+ PushExprKind push (*this , ExprKind::RValue);
969+ Convert (NormalizeToBool (cond, ctx_));
974970}
975971
976972bool Converter::VisitIfStmt (clang::IfStmt *stmt) {
@@ -1741,6 +1737,41 @@ void Converter::ConvertIntegerToEnumeralCast(clang::Expr *to,
17411737 }
17421738}
17431739
1740+ void Converter::ConvertIntegralToBooleanCast (clang::ImplicitCastExpr *expr) {
1741+ auto sub_expr = expr->getSubExpr ();
1742+ auto *stripped = sub_expr->IgnoreParenImpCasts ();
1743+
1744+ if (auto binop = clang::dyn_cast<clang::BinaryOperator>(stripped)) {
1745+ // Comparison already produces bool, no wrap needed.
1746+ if (binop->isComparisonOp ()) {
1747+ Convert (sub_expr);
1748+ return ;
1749+ }
1750+ // Distribute bool conversion to each argument of the logical op.
1751+ if (binop->isLogicalOp ()) {
1752+ {
1753+ PushParen paren (*this );
1754+ ConvertCondition (binop->getLHS ());
1755+ }
1756+ StrCat (binop->getOpcodeStr ());
1757+ {
1758+ PushParen paren (*this );
1759+ ConvertCondition (binop->getRHS ());
1760+ }
1761+ return ;
1762+ }
1763+ }
1764+
1765+ PushParen paren (*this );
1766+ Convert (sub_expr);
1767+ StrCat (token::kDiff );
1768+ if (sub_expr->getType ()->isEnumeralType ()) {
1769+ StrCat (GetUnsafeTypeAsString (sub_expr->getType ()), " ::from(0)" );
1770+ } else /* sub_expr->getType()->isIntegerType() */ {
1771+ StrCat (token::kZero );
1772+ }
1773+ }
1774+
17441775bool Converter::VisitImplicitCastExpr (clang::ImplicitCastExpr *expr) {
17451776 auto *sub_expr = expr->getSubExpr ();
17461777 auto type = expr->getType ();
@@ -1816,20 +1847,7 @@ bool Converter::VisitImplicitCastExpr(clang::ImplicitCastExpr *expr) {
18161847 Convert (sub_expr);
18171848 break ;
18181849 case clang::CastKind::CK_IntegralToBoolean:
1819- if (auto binop = clang::dyn_cast<clang::BinaryOperator>(
1820- sub_expr->IgnoreParenImpCasts ())) {
1821- // This already produces bool, no need for != 0
1822- if (binop->isComparisonOp ()) {
1823- Convert (sub_expr);
1824- break ;
1825- }
1826- }
1827-
1828- {
1829- PushParen paren (*this );
1830- Convert (sub_expr);
1831- StrCat (token::kDiff , token::kZero );
1832- }
1850+ ConvertIntegralToBooleanCast (expr);
18331851 break ;
18341852 case clang::CastKind::CK_PointerToBoolean:
18351853 StrCat (token::kNot );
@@ -2130,6 +2148,18 @@ bool Converter::VisitUnaryOperator(clang::UnaryOperator *expr) {
21302148 Convert (sub_expr);
21312149 computed_expr_type_ = ComputedExprType::FreshValue;
21322150 break ;
2151+ case clang::UO_LNot: {
2152+ bool needs_int_cast =
2153+ expr->getType ()->isIntegerType () && !expr->getType ()->isBooleanType ();
2154+ PushParen paren_cast (*this , needs_int_cast);
2155+ StrCat (token::kNot );
2156+ ConvertCondition (sub_expr);
2157+ if (needs_int_cast) {
2158+ ConvertCast (expr->getType ());
2159+ }
2160+ computed_expr_type_ = ComputedExprType::FreshValue;
2161+ break ;
2162+ }
21332163 case clang::UO_Minus:
21342164 if (auto *literal = clang::dyn_cast<clang::IntegerLiteral>(sub_expr)) {
21352165 if (sub_expr->getType ()->isUnsignedIntegerType ()) {
@@ -2173,7 +2203,7 @@ void Converter::EmitStmtExprTail(clang::Expr *tail) { Convert(tail); }
21732203
21742204bool Converter::VisitConditionalOperator (clang::ConditionalOperator *expr) {
21752205 StrCat (keyword::kIf );
2176- Convert (expr->getCond ());
2206+ ConvertCondition (expr->getCond ());
21772207 {
21782208 PushBrace then_brace (*this );
21792209 if (expr->isLValue () && !isRValue () && !expr->getType ()->isFunctionType ()) {
@@ -2290,21 +2320,11 @@ bool Converter::VisitParenExpr(clang::ParenExpr *expr) {
22902320 }
22912321 }
22922322
2293- // Add cast to avoid ambigous integers. Don't add cast if sub expression is a
2294- // pointer dereference because we might want to mutate the dereferenced value.
2295- bool should_add_integral_cast =
2296- expr->getType ()->isIntegralOrEnumerationType () && !isAddrOf () &&
2297- !isVoid () && !clang::isa<clang::UnaryOperator>(expr->getSubExpr ());
2298- PushParen outer (*this , should_add_integral_cast);
2299-
23002323 {
23012324 PushParen inner (*this );
23022325 Convert (expr->getSubExpr ());
23032326 }
23042327
2305- if (should_add_integral_cast) {
2306- ConvertCast (expr->getType ());
2307- }
23082328 return false ;
23092329}
23102330
0 commit comments