| ... | ... | @@ -954,13 +954,6 @@ fn transBinaryOperator( |
| 954 | 954 | } |
| 955 | 955 | const lhs_node = try transExpr(rp, scope, ZigClangBinaryOperator_getLHS(stmt), .used, .l_value); |
| 956 | 956 | switch (op) { |
| 957 | | .PtrMemD, .PtrMemI, .Cmp => return revertAndWarn( |
| 958 | | rp, |
| 959 | | error.UnsupportedTranslation, |
| 960 | | ZigClangBinaryOperator_getBeginLoc(stmt), |
| 961 | | "TODO: handle more C binary operators: {}", |
| 962 | | .{op}, |
| 963 | | ), |
| 964 | 957 | .Add => { |
| 965 | 958 | if (cIsUnsignedInteger(qt)) { |
| 966 | 959 | op_token = try appendToken(rp.c, .PlusPercent, "+%"); |
| ... | ... | @@ -1205,6 +1198,26 @@ fn transBoolExpr( |
| 1205 | 1198 | undefined; |
| 1206 | 1199 | var res = try transExpr(rp, scope, expr, used, lrvalue); |
| 1207 | 1200 | |
| 1201 | if (isBoolRes(res)) |
| 1202 | return res; |
| 1203 | const ty = ZigClangQualType_getTypePtr(getExprQualTypeBeforeImplicitCast(rp.c, expr)); |
| 1204 | const node = try finishBoolExpr(rp, scope, ZigClangExpr_getBeginLoc(expr), ty, res, used); |
| 1205 | |
| 1206 | if (grouped) { |
| 1207 | const rparen = try appendToken(rp.c, .RParen, ")"); |
| 1208 | const grouped_expr = try rp.c.a().create(ast.Node.GroupedExpression); |
| 1209 | grouped_expr.* = .{ |
| 1210 | .lparen = lparen, |
| 1211 | .expr = node, |
| 1212 | .rparen = rparen, |
| 1213 | }; |
| 1214 | return maybeSuppressResult(rp, scope, used, &grouped_expr.base); |
| 1215 | } else { |
| 1216 | return maybeSuppressResult(rp, scope, used, node); |
| 1217 | } |
| 1218 | } |
| 1219 | |
| 1220 | fn isBoolRes(res: *ast.Node) bool { |
| 1208 | 1221 | switch (res.id) { |
| 1209 | 1222 | .InfixOp => switch (@fieldParentPtr(ast.Node.InfixOp, "base", res).op) { |
| 1210 | 1223 | .BoolOr, |
| ... | ... | @@ -1215,23 +1228,20 @@ fn transBoolExpr( |
| 1215 | 1228 | .GreaterThan, |
| 1216 | 1229 | .LessOrEqual, |
| 1217 | 1230 | .GreaterOrEqual, |
| 1218 | | => return res, |
| 1231 | => return true, |
| 1219 | 1232 | |
| 1220 | 1233 | else => {}, |
| 1221 | 1234 | }, |
| 1222 | | |
| 1223 | 1235 | .PrefixOp => switch (@fieldParentPtr(ast.Node.PrefixOp, "base", res).op) { |
| 1224 | | .BoolNot => return res, |
| 1236 | .BoolNot => return true, |
| 1225 | 1237 | |
| 1226 | 1238 | else => {}, |
| 1227 | 1239 | }, |
| 1228 | | |
| 1229 | | .BoolLiteral => return res, |
| 1230 | | |
| 1240 | .BoolLiteral => return true, |
| 1241 | .GroupedExpression => return isBoolRes(@fieldParentPtr(ast.Node.GroupedExpression, "base", res).expr), |
| 1231 | 1242 | else => {}, |
| 1232 | 1243 | } |
| 1233 | | const ty = ZigClangQualType_getTypePtr(getExprQualTypeBeforeImplicitCast(rp.c, expr)); |
| 1234 | | return finishBoolExpr(rp, scope, ZigClangExpr_getBeginLoc(expr), ty, res, used, grouped); |
| 1244 | return false; |
| 1235 | 1245 | } |
| 1236 | 1246 | |
| 1237 | 1247 | fn finishBoolExpr( |
| ... | ... | @@ -1241,14 +1251,13 @@ fn finishBoolExpr( |
| 1241 | 1251 | ty: *const ZigClangType, |
| 1242 | 1252 | node: *ast.Node, |
| 1243 | 1253 | used: ResultUsed, |
| 1244 | | grouped: bool, |
| 1245 | 1254 | ) TransError!*ast.Node { |
| 1246 | 1255 | switch (ZigClangType_getTypeClass(ty)) { |
| 1247 | 1256 | .Builtin => { |
| 1248 | 1257 | const builtin_ty = @ptrCast(*const ZigClangBuiltinType, ty); |
| 1249 | 1258 | |
| 1250 | 1259 | switch (ZigClangBuiltinType_getKind(builtin_ty)) { |
| 1251 | | .Bool, |
| 1260 | .Bool => return node, |
| 1252 | 1261 | .Char_U, |
| 1253 | 1262 | .UChar, |
| 1254 | 1263 | .Char_S, |
| ... | ... | @@ -1276,12 +1285,12 @@ fn finishBoolExpr( |
| 1276 | 1285 | => { |
| 1277 | 1286 | const op_token = try appendToken(rp.c, .BangEqual, "!="); |
| 1278 | 1287 | const rhs_node = try transCreateNodeInt(rp.c, 0); |
| 1279 | | return transCreateNodeInfixOp(rp, scope, node, .BangEqual, op_token, rhs_node, used, grouped); |
| 1288 | return transCreateNodeInfixOp(rp, scope, node, .BangEqual, op_token, rhs_node, used, false); |
| 1280 | 1289 | }, |
| 1281 | 1290 | .NullPtr => { |
| 1282 | 1291 | const op_token = try appendToken(rp.c, .EqualEqual, "=="); |
| 1283 | 1292 | const rhs_node = try transCreateNodeNullLiteral(rp.c); |
| 1284 | | return transCreateNodeInfixOp(rp, scope, node, .EqualEqual, op_token, rhs_node, used, grouped); |
| 1293 | return transCreateNodeInfixOp(rp, scope, node, .EqualEqual, op_token, rhs_node, used, false); |
| 1285 | 1294 | }, |
| 1286 | 1295 | else => {}, |
| 1287 | 1296 | } |
| ... | ... | @@ -1289,13 +1298,13 @@ fn finishBoolExpr( |
| 1289 | 1298 | .Pointer => { |
| 1290 | 1299 | const op_token = try appendToken(rp.c, .BangEqual, "!="); |
| 1291 | 1300 | const rhs_node = try transCreateNodeNullLiteral(rp.c); |
| 1292 | | return transCreateNodeInfixOp(rp, scope, node, .BangEqual, op_token, rhs_node, used, grouped); |
| 1301 | return transCreateNodeInfixOp(rp, scope, node, .BangEqual, op_token, rhs_node, used, false); |
| 1293 | 1302 | }, |
| 1294 | 1303 | .Typedef => { |
| 1295 | 1304 | const typedef_ty = @ptrCast(*const ZigClangTypedefType, ty); |
| 1296 | 1305 | const typedef_decl = ZigClangTypedefType_getDecl(typedef_ty); |
| 1297 | 1306 | const underlying_type = ZigClangTypedefNameDecl_getUnderlyingType(typedef_decl); |
| 1298 | | return finishBoolExpr(rp, scope, loc, ZigClangQualType_getTypePtr(underlying_type), node, used, grouped); |
| 1307 | return finishBoolExpr(rp, scope, loc, ZigClangQualType_getTypePtr(underlying_type), node, used); |
| 1299 | 1308 | }, |
| 1300 | 1309 | .Enum => { |
| 1301 | 1310 | const enum_ty = @ptrCast(*const ZigClangEnumType, ty); |
| ... | ... | @@ -1305,12 +1314,12 @@ fn finishBoolExpr( |
| 1305 | 1314 | |
| 1306 | 1315 | const op_token = try appendToken(rp.c, .BangEqual, "!="); |
| 1307 | 1316 | const rhs_node = try transCreateNodeInt(rp.c, 0); |
| 1308 | | return transCreateNodeInfixOp(rp, scope, &builtin_node.base, .BangEqual, op_token, rhs_node, used, grouped); |
| 1317 | return transCreateNodeInfixOp(rp, scope, &builtin_node.base, .BangEqual, op_token, rhs_node, used, false); |
| 1309 | 1318 | }, |
| 1310 | 1319 | .Elaborated => { |
| 1311 | 1320 | const elaborated_ty = @ptrCast(*const ZigClangElaboratedType, ty); |
| 1312 | 1321 | const named_type = ZigClangElaboratedType_getNamedType(elaborated_ty); |
| 1313 | | return finishBoolExpr(rp, scope, loc, ZigClangQualType_getTypePtr(named_type), node, used, grouped); |
| 1322 | return finishBoolExpr(rp, scope, loc, ZigClangQualType_getTypePtr(named_type), node, used); |
| 1314 | 1323 | }, |
| 1315 | 1324 | else => {}, |
| 1316 | 1325 | } |
| ... | ... | @@ -2009,8 +2018,8 @@ fn transFloatingLiteral(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangFl |
| 2009 | 2018 | } |
| 2010 | 2019 | |
| 2011 | 2020 | fn transConditionalOperator(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangConditionalOperator, used: ResultUsed) TransError!*ast.Node { |
| 2012 | | const gropued = scope.id == .Condition; |
| 2013 | | const lparen = if (gropued) try appendToken(rp.c, .LParen, "(") else undefined; |
| 2021 | const grouped = scope.id == .Condition; |
| 2022 | const lparen = if (grouped) try appendToken(rp.c, .LParen, "(") else undefined; |
| 2014 | 2023 | const if_node = try transCreateNodeIf(rp.c); |
| 2015 | 2024 | var cond_scope = Scope{ |
| 2016 | 2025 | .parent = scope, |
| ... | ... | @@ -2029,7 +2038,7 @@ fn transConditionalOperator(rp: RestorePoint, scope: *Scope, stmt: *const ZigCla |
| 2029 | 2038 | if_node.@"else" = try transCreateNodeElse(rp.c); |
| 2030 | 2039 | if_node.@"else".?.body = try transExpr(rp, scope, false_expr, .used, .r_value); |
| 2031 | 2040 | |
| 2032 | | if (gropued) { |
| 2041 | if (grouped) { |
| 2033 | 2042 | const rparen = try appendToken(rp.c, .RParen, ")"); |
| 2034 | 2043 | const grouped_expr = try rp.c.a().create(ast.Node.GroupedExpression); |
| 2035 | 2044 | grouped_expr.* = .{ |