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