authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2019-12-19 01:38:42+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2019-12-19 01:38:42+02:00
log122a9bad3973bb9f7f48c91eb45cbf0513cf19c3
treea71ab8843c6f0dd648e5b88aaebaa89395c71f7a
parentd54c288bd351adb84dd98b26848687d66cb725dc
signature Commit is signed but in an unrecognized format.

translate-c-2 fix some casts


5 files changed, 306 insertions(+), 187 deletions(-)

src-self-hosted/clang.zig+2
...@@ -761,6 +761,8 @@ pub extern fn ZigClangEnumType_getDecl(record_ty: ?*const struct_ZigClangEnumTyp...@@ -761,6 +761,8 @@ pub extern fn ZigClangEnumType_getDecl(record_ty: ?*const struct_ZigClangEnumTyp
761pub extern fn ZigClangRecordDecl_getCanonicalDecl(record_decl: ?*const struct_ZigClangRecordDecl) ?*const struct_ZigClangTagDecl;761pub extern fn ZigClangRecordDecl_getCanonicalDecl(record_decl: ?*const struct_ZigClangRecordDecl) ?*const struct_ZigClangTagDecl;
762pub extern fn ZigClangEnumDecl_getCanonicalDecl(self: ?*const struct_ZigClangEnumDecl) ?*const struct_ZigClangTagDecl;762pub extern fn ZigClangEnumDecl_getCanonicalDecl(self: ?*const struct_ZigClangEnumDecl) ?*const struct_ZigClangTagDecl;
763pub extern fn ZigClangTypedefNameDecl_getCanonicalDecl(self: ?*const struct_ZigClangTypedefNameDecl) ?*const struct_ZigClangTypedefNameDecl;763pub extern fn ZigClangTypedefNameDecl_getCanonicalDecl(self: ?*const struct_ZigClangTypedefNameDecl) ?*const struct_ZigClangTypedefNameDecl;
764pub extern fn ZigClangFunctionDecl_getCanonicalDecl(self: ?*const struct_ZigClangFunctionDecl) ?*const struct_ZigClangFunctionDecl;
765pub extern fn ZigClangVarDecl_getCanonicalDecl(self: ?*const struct_ZigClangVarDecl) ?*const struct_ZigClangVarDecl;
764pub extern fn ZigClangRecordDecl_getDefinition(self: ?*const struct_ZigClangRecordDecl) ?*const struct_ZigClangRecordDecl;766pub extern fn ZigClangRecordDecl_getDefinition(self: ?*const struct_ZigClangRecordDecl) ?*const struct_ZigClangRecordDecl;
765pub extern fn ZigClangEnumDecl_getDefinition(self: ?*const struct_ZigClangEnumDecl) ?*const struct_ZigClangEnumDecl;767pub extern fn ZigClangEnumDecl_getDefinition(self: ?*const struct_ZigClangEnumDecl) ?*const struct_ZigClangEnumDecl;
766pub extern fn ZigClangRecordDecl_getLocation(self: ?*const struct_ZigClangRecordDecl) struct_ZigClangSourceLocation;768pub extern fn ZigClangRecordDecl_getLocation(self: ?*const struct_ZigClangRecordDecl) struct_ZigClangSourceLocation;
src-self-hosted/translate_c.zig+53-11
...@@ -375,7 +375,8 @@ fn declVisitor(c: *Context, decl: *const ZigClangDecl) Error!void {...@@ -375,7 +375,8 @@ fn declVisitor(c: *Context, decl: *const ZigClangDecl) Error!void {
375}375}
376376
377fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {377fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {
378 if (c.decl_table.contains(@ptrToInt(fn_decl))) return; // Avoid processing this decl twice378 if (c.decl_table.contains(@ptrToInt(ZigClangFunctionDecl_getCanonicalDecl(fn_decl))))
379 return; // Avoid processing this decl twice
379 const rp = makeRestorePoint(c);380 const rp = makeRestorePoint(c);
380 const fn_name = try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, fn_decl)));381 const fn_name = try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, fn_decl)));
381 _ = try c.decl_table.put(@ptrToInt(fn_decl), fn_name);382 _ = try c.decl_table.put(@ptrToInt(fn_decl), fn_name);
...@@ -442,7 +443,8 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {...@@ -442,7 +443,8 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {
442}443}
443444
444fn visitVarDecl(c: *Context, var_decl: *const ZigClangVarDecl) Error!void {445fn visitVarDecl(c: *Context, var_decl: *const ZigClangVarDecl) Error!void {
445 if (c.decl_table.contains(@ptrToInt(var_decl))) return; // Avoid processing this decl twice446 if (c.decl_table.contains(@ptrToInt(ZigClangVarDecl_getCanonicalDecl(var_decl))))
447 return; // Avoid processing this decl twice
446 const rp = makeRestorePoint(c);448 const rp = makeRestorePoint(c);
447 const visib_tok = try appendToken(c, .Keyword_pub, "pub");449 const visib_tok = try appendToken(c, .Keyword_pub, "pub");
448450
...@@ -1115,10 +1117,17 @@ fn transDeclStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangDeclStmt)...@@ -1115,10 +1117,17 @@ fn transDeclStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangDeclStmt)
1115 node.type_node = try transQualType(rp, qual_type, loc);1117 node.type_node = try transQualType(rp, qual_type, loc);
11161118
1117 node.eq_token = try appendToken(c, .Equal, "=");1119 node.eq_token = try appendToken(c, .Equal, "=");
1118 node.init_node = if (ZigClangVarDecl_getInit(var_decl)) |expr|1120 var init_node = if (ZigClangVarDecl_getInit(var_decl)) |expr|
1119 try transExpr(rp, scope, expr, .used, .r_value)1121 try transExpr(rp, scope, expr, .used, .r_value)
1120 else1122 else
1121 try transCreateNodeUndefinedLiteral(c);1123 try transCreateNodeUndefinedLiteral(c);
1124 if (isBoolRes(init_node)) {
1125 const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt");
1126 try builtin_node.params.push(init_node);
1127 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
1128 init_node = &builtin_node.base;
1129 }
1130 node.init_node = init_node;
1122 node.semicolon_token = try appendToken(c, .Semicolon, ";");1131 node.semicolon_token = try appendToken(c, .Semicolon, ";");
1123 try block_scope.block_node.statements.push(&node.base);1132 try block_scope.block_node.statements.push(&node.base);
1124 },1133 },
...@@ -1300,14 +1309,9 @@ fn finishBoolExpr(...@@ -1300,14 +1309,9 @@ fn finishBoolExpr(
1300 return finishBoolExpr(rp, scope, loc, ZigClangQualType_getTypePtr(underlying_type), node, used);1309 return finishBoolExpr(rp, scope, loc, ZigClangQualType_getTypePtr(underlying_type), node, used);
1301 },1310 },
1302 .Enum => {1311 .Enum => {
1303 const enum_ty = @ptrCast(*const ZigClangEnumType, ty);
1304 const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@enumToInt");
1305 try builtin_node.params.push(node);
1306 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
1307
1308 const op_token = try appendToken(rp.c, .BangEqual, "!=");1312 const op_token = try appendToken(rp.c, .BangEqual, "!=");
1309 const rhs_node = try transCreateNodeInt(rp.c, 0);1313 const rhs_node = try transCreateNodeInt(rp.c, 0);
1310 return transCreateNodeInfixOp(rp, scope, &builtin_node.base, .BangEqual, op_token, rhs_node, used, false);1314 return transCreateNodeInfixOp(rp, scope, node, .BangEqual, op_token, rhs_node, used, false);
1311 },1315 },
1312 .Elaborated => {1316 .Elaborated => {
1313 const elaborated_ty = @ptrCast(*const ZigClangElaboratedType, ty);1317 const elaborated_ty = @ptrCast(*const ZigClangElaboratedType, ty);
...@@ -1472,6 +1476,31 @@ fn transCCast(...@@ -1472,6 +1476,31 @@ fn transCCast(
1472 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");1476 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
1473 return &builtin_node.base;1477 return &builtin_node.base;
1474 }1478 }
1479 if (ZigClangQualType_getTypeClass(src_type) == .Elaborated) {
1480 const elaborated_ty = @ptrCast(*const ZigClangElaboratedType, ZigClangQualType_getTypePtr(src_type));
1481 return transCCast(rp, scope, loc, dst_type, ZigClangElaboratedType_getNamedType(elaborated_ty), expr);
1482 }
1483 if (ZigClangQualType_getTypeClass(dst_type) == .Elaborated) {
1484 const elaborated_ty = @ptrCast(*const ZigClangElaboratedType, ZigClangQualType_getTypePtr(dst_type));
1485 return transCCast(rp, scope, loc, ZigClangElaboratedType_getNamedType(elaborated_ty), src_type, expr);
1486 }
1487 if (ZigClangQualType_getTypeClass(src_type) == .Enum and
1488 ZigClangQualType_getTypeClass(dst_type) != .Enum) {
1489 const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@enumToInt");
1490 try builtin_node.params.push(expr);
1491 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
1492 return &builtin_node.base;
1493 }
1494 // TODO
1495 // if (ZigClangQualType_getTypeClass(dst_type) == .Enum and
1496 // ZigClangQualType_getTypeClass(src_type) != .Enum) {
1497 // const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@intToEnum");
1498 // try builtin_node.params.push(try transQualType(rp, dst_type, loc));
1499 // _ = try appendToken(rp.c, .Comma, ",");
1500 // try builtin_node.params.push(expr);
1501 // builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
1502 // return &builtin_node.base;
1503 // }
1475 // TODO: maybe widen to increase size1504 // TODO: maybe widen to increase size
1476 // TODO: maybe bitcast to change sign1505 // TODO: maybe bitcast to change sign
1477 // TODO: maybe truncate to reduce size1506 // TODO: maybe truncate to reduce size
...@@ -2443,7 +2472,13 @@ fn transCreateNodeAssign(...@@ -2443,7 +2472,13 @@ fn transCreateNodeAssign(
2443 if (result_used == .unused) {2472 if (result_used == .unused) {
2444 const lhs_node = try transExpr(rp, scope, lhs, .used, .l_value);2473 const lhs_node = try transExpr(rp, scope, lhs, .used, .l_value);
2445 const eq_token = try appendToken(rp.c, .Equal, "=");2474 const eq_token = try appendToken(rp.c, .Equal, "=");
2446 const rhs_node = try transExpr(rp, scope, rhs, .used, .r_value);2475 var rhs_node = try transExpr(rp, scope, rhs, .used, .r_value);
2476 if (isBoolRes(rhs_node)) {
2477 const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt");
2478 try builtin_node.params.push(rhs_node);
2479 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
2480 rhs_node = &builtin_node.base;
2481 }
2447 if (scope.id != .Condition)2482 if (scope.id != .Condition)
2448 _ = try appendToken(rp.c, .Semicolon, ";");2483 _ = try appendToken(rp.c, .Semicolon, ";");
24492484
...@@ -2471,7 +2506,14 @@ fn transCreateNodeAssign(...@@ -2471,7 +2506,14 @@ fn transCreateNodeAssign(
24712506
2472 const node = try transCreateNodeVarDecl(rp.c, false, true, tmp);2507 const node = try transCreateNodeVarDecl(rp.c, false, true, tmp);
2473 node.eq_token = try appendToken(rp.c, .Equal, "=");2508 node.eq_token = try appendToken(rp.c, .Equal, "=");
2474 node.init_node = try transExpr(rp, scope, rhs, .used, .r_value);2509 var rhs_node = try transExpr(rp, scope, rhs, .used, .r_value);
2510 if (isBoolRes(rhs_node)) {
2511 const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt");
2512 try builtin_node.params.push(rhs_node);
2513 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
2514 rhs_node = &builtin_node.base;
2515 }
2516 node.init_node = rhs_node;
2475 node.semicolon_token = try appendToken(rp.c, .Semicolon, ";");2517 node.semicolon_token = try appendToken(rp.c, .Semicolon, ";");
2476 try block_scope.block_node.statements.push(&node.base);2518 try block_scope.block_node.statements.push(&node.base);
24772519
src/zig_clang.cpp+10
...@@ -1571,6 +1571,16 @@ const ZigClangTypedefNameDecl *ZigClangTypedefNameDecl_getCanonicalDecl(const Zi...@@ -1571,6 +1571,16 @@ const ZigClangTypedefNameDecl *ZigClangTypedefNameDecl_getCanonicalDecl(const Zi
1571 return reinterpret_cast<const ZigClangTypedefNameDecl *>(decl);1571 return reinterpret_cast<const ZigClangTypedefNameDecl *>(decl);
1572}1572}
15731573
1574const ZigClangFunctionDecl *ZigClangFunctionDecl_getCanonicalDecl(const ZigClangFunctionDecl *self) {
1575 const clang::FunctionDecl *decl = reinterpret_cast<const clang::FunctionDecl*>(self)->getCanonicalDecl();
1576 return reinterpret_cast<const ZigClangFunctionDecl *>(decl);
1577}
1578
1579const ZigClangVarDecl *ZigClangVarDecl_getCanonicalDecl(const ZigClangVarDecl *self) {
1580 const clang::VarDecl *decl = reinterpret_cast<const clang::VarDecl*>(self)->getCanonicalDecl();
1581 return reinterpret_cast<const ZigClangVarDecl *>(decl);
1582}
1583
1574const ZigClangRecordDecl *ZigClangRecordDecl_getDefinition(const ZigClangRecordDecl *zig_record_decl) {1584const ZigClangRecordDecl *ZigClangRecordDecl_getDefinition(const ZigClangRecordDecl *zig_record_decl) {
1575 const clang::RecordDecl *record_decl = reinterpret_cast<const clang::RecordDecl *>(zig_record_decl);1585 const clang::RecordDecl *record_decl = reinterpret_cast<const clang::RecordDecl *>(zig_record_decl);
1576 const clang::RecordDecl *definition = record_decl->getDefinition();1586 const clang::RecordDecl *definition = record_decl->getDefinition();
src/zig_clang.h+2
...@@ -856,6 +856,8 @@ ZIG_EXTERN_C const struct ZigClangEnumDecl *ZigClangEnumType_getDecl(const struc...@@ -856,6 +856,8 @@ ZIG_EXTERN_C const struct ZigClangEnumDecl *ZigClangEnumType_getDecl(const struc
856ZIG_EXTERN_C const struct ZigClangTagDecl *ZigClangRecordDecl_getCanonicalDecl(const struct ZigClangRecordDecl *record_decl);856ZIG_EXTERN_C const struct ZigClangTagDecl *ZigClangRecordDecl_getCanonicalDecl(const struct ZigClangRecordDecl *record_decl);
857ZIG_EXTERN_C const struct ZigClangTagDecl *ZigClangEnumDecl_getCanonicalDecl(const struct ZigClangEnumDecl *);857ZIG_EXTERN_C const struct ZigClangTagDecl *ZigClangEnumDecl_getCanonicalDecl(const struct ZigClangEnumDecl *);
858ZIG_EXTERN_C const struct ZigClangTypedefNameDecl *ZigClangTypedefNameDecl_getCanonicalDecl(const struct ZigClangTypedefNameDecl *);858ZIG_EXTERN_C const struct ZigClangTypedefNameDecl *ZigClangTypedefNameDecl_getCanonicalDecl(const struct ZigClangTypedefNameDecl *);
859ZIG_EXTERN_C const struct ZigClangFunctionDecl *ZigClangFunctionDecl_getCanonicalDecl(const ZigClangFunctionDecl *self);
860ZIG_EXTERN_C const struct ZigClangVarDecl *ZigClangVarDecl_getCanonicalDecl(const ZigClangVarDecl *self);
859861
860ZIG_EXTERN_C const struct ZigClangRecordDecl *ZigClangRecordDecl_getDefinition(const struct ZigClangRecordDecl *);862ZIG_EXTERN_C const struct ZigClangRecordDecl *ZigClangRecordDecl_getDefinition(const struct ZigClangRecordDecl *);
861ZIG_EXTERN_C const struct ZigClangEnumDecl *ZigClangEnumDecl_getDefinition(const struct ZigClangEnumDecl *);863ZIG_EXTERN_C const struct ZigClangEnumDecl *ZigClangEnumDecl_getDefinition(const struct ZigClangEnumDecl *);
test/translate_c.zig+239-176
...@@ -716,6 +716,38 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -716,6 +716,38 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
716 \\}716 \\}
717 });717 });
718718
719 cases.addC_both("while on non-bool",
720 \\int while_none_bool(int a, float b, void *c) {
721 \\ while (a) return 0;
722 \\ while (b) return 1;
723 \\ while (c) return 2;
724 \\ return 3;
725 \\}
726 , &[_][]const u8{
727 \\pub export fn while_none_bool(a: c_int, b: f32, c: ?*c_void) c_int {
728 \\ while (a != 0) return 0;
729 \\ while (b != 0) return 1;
730 \\ while (c != null) return 2;
731 \\ return 3;
732 \\}
733 });
734
735 cases.addC_both("for on non-bool",
736 \\int for_none_bool(int a, float b, void *c) {
737 \\ for (;a;) return 0;
738 \\ for (;b;) return 1;
739 \\ for (;c;) return 2;
740 \\ return 3;
741 \\}
742 , &[_][]const u8{
743 \\pub export fn for_none_bool(a: c_int, b: f32, c: ?*c_void) c_int {
744 \\ while (a != 0) return 0;
745 \\ while (b != 0) return 1;
746 \\ while (c != null) return 2;
747 \\ return 3;
748 \\}
749 });
750
719 /////////////// Cases that pass for only stage2 ////////////////751 /////////////// Cases that pass for only stage2 ////////////////
720752
721 cases.add_2("Parameterless function prototypes",753 cases.add_2("Parameterless function prototypes",
...@@ -1369,18 +1401,18 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1369,18 +1401,18 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1369 \\pub const SomeTypedef = c_int;1401 \\pub const SomeTypedef = c_int;
1370 \\pub export fn and_or_non_bool(a: c_int, b: f32, c: ?*c_void) c_int {1402 \\pub export fn and_or_non_bool(a: c_int, b: f32, c: ?*c_void) c_int {
1371 \\ var d: enum_Foo = @as(enum_Foo, FooA);1403 \\ var d: enum_Foo = @as(enum_Foo, FooA);
1372 \\ var e: c_int = ((a != 0) and (b != 0));1404 \\ var e: c_int = @boolToInt(((a != 0) and (b != 0)));
1373 \\ var f: c_int = ((b != 0) and (c != null));1405 \\ var f: c_int = @boolToInt(((b != 0) and (c != null)));
1374 \\ var g: c_int = ((a != 0) and (c != null));1406 \\ var g: c_int = @boolToInt(((a != 0) and (c != null)));
1375 \\ var h: c_int = ((a != 0) or (b != 0));1407 \\ var h: c_int = @boolToInt(((a != 0) or (b != 0)));
1376 \\ var i: c_int = ((b != 0) or (c != null));1408 \\ var i: c_int = @boolToInt(((b != 0) or (c != null)));
1377 \\ var j: c_int = ((a != 0) or (c != null));1409 \\ var j: c_int = @boolToInt(((a != 0) or (c != null)));
1378 \\ var k: c_int = ((a != 0) or (@enumToInt(@as(c_uint, d)) != 0));1410 \\ var k: c_int = @boolToInt(((a != 0) or (@enumToInt(d) != 0)));
1379 \\ var l: c_int = ((@enumToInt(@as(c_uint, d)) != 0) and (b != 0));1411 \\ var l: c_int = @boolToInt(((@enumToInt(d) != 0) and (b != 0)));
1380 \\ var m: c_int = ((c != null) or (@enumToInt(@as(c_uint, d)) != 0));1412 \\ var m: c_int = @boolToInt(((c != null) or (@enumToInt(d) != 0)));
1381 \\ var td: SomeTypedef = 44;1413 \\ var td: SomeTypedef = 44;
1382 \\ var o: c_int = ((td != 0) or (b != 0));1414 \\ var o: c_int = @boolToInt(((td != 0) or (b != 0)));
1383 \\ var p: c_int = ((c != null) and (td != 0));1415 \\ var p: c_int = @boolToInt(((c != null) and (td != 0)));
1384 \\ return ((((((((((e + f) + g) + h) + i) + j) + k) + l) + m) + o) + p);1416 \\ return ((((((((((e + f) + g) + h) + i) + j) + k) + l) + m) + o) + p);
1385 \\}1417 \\}
1386 ,1418 ,
...@@ -1437,13 +1469,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1437,13 +1469,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1437 \\}1469 \\}
1438 , &[_][]const u8{1470 , &[_][]const u8{
1439 \\pub export fn test_comparisons(a: c_int, b: c_int) c_int {1471 \\pub export fn test_comparisons(a: c_int, b: c_int) c_int {
1440 \\ var c: c_int = (a < b);1472 \\ var c: c_int = @boolToInt((a < b));
1441 \\ var d: c_int = (a > b);1473 \\ var d: c_int = @boolToInt((a > b));
1442 \\ var e: c_int = (a <= b);1474 \\ var e: c_int = @boolToInt((a <= b));
1443 \\ var f: c_int = (a >= b);1475 \\ var f: c_int = @boolToInt((a >= b));
1444 \\ var g: c_int = (c < d);1476 \\ var g: c_int = @boolToInt((c < d));
1445 \\ var h: c_int = (e < f);1477 \\ var h: c_int = @boolToInt((e < f));
1446 \\ var i: c_int = (g < h);1478 \\ var i: c_int = @boolToInt((g < h));
1447 \\ return i;1479 \\ return i;
1448 \\}1480 \\}
1449 });1481 });
...@@ -1560,6 +1592,69 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1560,6 +1592,69 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1560 \\}1592 \\}
1561 });1593 });
15621594
1595 cases.add_2("logical and, logical or",
1596 \\int max(int a, int b) {
1597 \\ if (a < b || a == b)
1598 \\ return b;
1599 \\ if (a >= b && a == b)
1600 \\ return a;
1601 \\ return a;
1602 \\}
1603 , &[_][]const u8{
1604 \\pub export fn max(a: c_int, b: c_int) c_int {
1605 \\ if (((a < b) or (a == b))) return b;
1606 \\ if (((a >= b) and (a == b))) return a;
1607 \\ return a;
1608 \\}
1609 });
1610
1611 cases.add_2("if statement",
1612 \\int max(int a, int b) {
1613 \\ if (a < b)
1614 \\ return b;
1615 \\
1616 \\ if (a < b)
1617 \\ return b;
1618 \\ else
1619 \\ return a;
1620 \\
1621 \\ if (a < b) ; else ;
1622 \\}
1623 , &[_][]const u8{
1624 \\pub export fn max(a: c_int, b: c_int) c_int {
1625 \\ if ((a < b)) return b;
1626 \\ if ((a < b)) return b else return a;
1627 \\ if ((a < b)) {} else {}
1628 \\}
1629 });
1630
1631 cases.add_2("if on non-bool",
1632 \\enum SomeEnum { A, B, C };
1633 \\int if_none_bool(int a, float b, void *c, enum SomeEnum d) {
1634 \\ if (a) return 0;
1635 \\ if (b) return 1;
1636 \\ if (c) return 2;
1637 \\ if (d) return 3;
1638 \\ return 4;
1639 \\}
1640 , &[_][]const u8{
1641 \\pub const A = enum_SomeEnum.A;
1642 \\pub const B = enum_SomeEnum.B;
1643 \\pub const C = enum_SomeEnum.C;
1644 \\pub const enum_SomeEnum = extern enum {
1645 \\ A,
1646 \\ B,
1647 \\ C,
1648 \\};
1649 \\pub export fn if_none_bool(a: c_int, b: f32, c: ?*c_void, d: enum_SomeEnum) c_int {
1650 \\ if (a != 0) return 0;
1651 \\ if (b != 0) return 1;
1652 \\ if (c != null) return 2;
1653 \\ if (d != 0) return 3;
1654 \\ return 4;
1655 \\}
1656 });
1657
1563 /////////////// Cases for only stage1 which are TODO items for stage2 ////////////////1658 /////////////// Cases for only stage1 which are TODO items for stage2 ////////////////
15641659
1565 cases.addAllowWarnings("simple data types",1660 cases.addAllowWarnings("simple data types",
...@@ -1651,85 +1746,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1651,85 +1746,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1651 \\}1746 \\}
1652 });1747 });
16531748
1654 cases.addC("if statement",
1655 \\int max(int a, int b) {
1656 \\ if (a < b)
1657 \\ return b;
1658 \\
1659 \\ if (a < b)
1660 \\ return b;
1661 \\ else
1662 \\ return a;
1663 \\
1664 \\ if (a < b) ; else ;
1665 \\}
1666 , &[_][]const u8{
1667 \\pub export fn max(a: c_int, b: c_int) c_int {
1668 \\ if (a < b) return b;
1669 \\ if (a < b) return b else return a;
1670 \\ if (a < b) {} else {}
1671 \\}
1672 });
1673
1674 cases.addC("logical and, logical or",
1675 \\int max(int a, int b) {
1676 \\ if (a < b || a == b)
1677 \\ return b;
1678 \\ if (a >= b && a == b)
1679 \\ return a;
1680 \\ return a;
1681 \\}
1682 , &[_][]const u8{
1683 \\pub export fn max(a: c_int, b: c_int) c_int {
1684 \\ if ((a < b) or (a == b)) return b;
1685 \\ if ((a >= b) and (a == b)) return a;
1686 \\ return a;
1687 \\}
1688 });
1689
1690 cases.addC("logical and, logical or, on non-bool values", // Note this gets cut off by extra C symbols being injected in middle: `pub const Foo = enum_Foo;`
1691 \\enum Foo {
1692 \\ FooA,
1693 \\ FooB,
1694 \\ FooC,
1695 \\};
1696 \\int and_or_non_bool(int a, float b, void *c) {
1697 \\ enum Foo d = FooA;
1698 \\ int e = (a && b);
1699 \\ int f = (b && c);
1700 \\ int g = (a && c);
1701 \\ int h = (a || b);
1702 \\ int i = (b || c);
1703 \\ int j = (a || c);
1704 \\ int k = (a || d);
1705 \\ int l = (d && b);
1706 \\ int m = (c || d);
1707 \\ return (((((((e + f) + g) + h) + i) + j) + k) + l) + m;
1708 \\}
1709 , &[_][]const u8{
1710 \\pub const FooA = enum_Foo.A;
1711 \\pub const FooB = enum_Foo.B;
1712 \\pub const FooC = enum_Foo.C;
1713 \\pub const enum_Foo = extern enum {
1714 \\ A,
1715 \\ B,
1716 \\ C,
1717 \\};
1718 \\pub export fn and_or_non_bool(a: c_int, b: f32, c: ?*c_void) c_int {
1719 \\ var d: enum_Foo = @as(enum_Foo, FooA);
1720 \\ var e: c_int = (a != 0) and (b != 0);
1721 \\ var f: c_int = (b != 0) and (c != null);
1722 \\ var g: c_int = (a != 0) and (c != null);
1723 \\ var h: c_int = (a != 0) or (b != 0);
1724 \\ var i: c_int = (b != 0) or (c != null);
1725 \\ var j: c_int = (a != 0) or (c != null);
1726 \\ var k: c_int = (a != 0) or (@as(c_uint, d) != @bitCast(enum_Foo, @as(@TagType(enum_Foo), 0)));
1727 \\ var l: c_int = (@as(c_uint, d) != @bitCast(enum_Foo, @as(@TagType(enum_Foo), 0))) and (b != 0);
1728 \\ var m: c_int = (c != null) or (@as(c_uint, d) != @bitCast(enum_Foo, @as(@TagType(enum_Foo), 0)));
1729 \\ return (((((((e + f) + g) + h) + i) + j) + k) + l) + m;
1730 \\}
1731 });
1732
1733 cases.addC("shift right assign with a fixed size type",1749 cases.addC("shift right assign with a fixed size type",
1734 \\#include <stdint.h>1750 \\#include <stdint.h>
1735 \\int log2(uint32_t a) {1751 \\int log2(uint32_t a) {
...@@ -2043,26 +2059,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -2043,26 +2059,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
2043 \\}2059 \\}
2044 });2060 });
20452061
2046 cases.add("variable name shadowing",
2047 \\int foo(void) {
2048 \\ int x = 1;
2049 \\ {
2050 \\ int x = 2;
2051 \\ x += 1;
2052 \\ }
2053 \\ return x;
2054 \\}
2055 , &[_][]const u8{
2056 \\pub fn foo() c_int {
2057 \\ var x: c_int = 1;
2058 \\ {
2059 \\ var x_0: c_int = 2;
2060 \\ x_0 += 1;
2061 \\ }
2062 \\ return x;
2063 \\}
2064 });
2065
2066 cases.add("bin not",2062 cases.add("bin not",
2067 \\int foo(int x) {2063 \\int foo(int x) {
2068 \\ return ~x;2064 \\ return ~x;
...@@ -2099,65 +2095,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -2099,65 +2095,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
2099 \\}2095 \\}
2100 });2096 });
21012097
2102 cases.add("if on non-bool",
2103 \\enum SomeEnum { A, B, C };
2104 \\int if_none_bool(int a, float b, void *c, enum SomeEnum d) {
2105 \\ if (a) return 0;
2106 \\ if (b) return 1;
2107 \\ if (c) return 2;
2108 \\ if (d) return 3;
2109 \\ return 4;
2110 \\}
2111 , &[_][]const u8{
2112 \\pub const A = enum_SomeEnum.A;
2113 \\pub const B = enum_SomeEnum.B;
2114 \\pub const C = enum_SomeEnum.C;
2115 \\pub const enum_SomeEnum = extern enum {
2116 \\ A,
2117 \\ B,
2118 \\ C,
2119 \\};
2120 \\pub fn if_none_bool(a: c_int, b: f32, c: ?*c_void, d: enum_SomeEnum) c_int {
2121 \\ if (a != 0) return 0;
2122 \\ if (b != 0) return 1;
2123 \\ if (c != null) return 2;
2124 \\ if (d != @bitCast(enum_SomeEnum, @as(@TagType(enum_SomeEnum), 0))) return 3;
2125 \\ return 4;
2126 \\}
2127 });
2128
2129 cases.add("while on non-bool",
2130 \\int while_none_bool(int a, float b, void *c) {
2131 \\ while (a) return 0;
2132 \\ while (b) return 1;
2133 \\ while (c) return 2;
2134 \\ return 3;
2135 \\}
2136 , &[_][]const u8{
2137 \\pub fn while_none_bool(a: c_int, b: f32, c: ?*c_void) c_int {
2138 \\ while (a != 0) return 0;
2139 \\ while (b != 0) return 1;
2140 \\ while (c != null) return 2;
2141 \\ return 3;
2142 \\}
2143 });
2144
2145 cases.add("for on non-bool",
2146 \\int for_none_bool(int a, float b, void *c) {
2147 \\ for (;a;) return 0;
2148 \\ for (;b;) return 1;
2149 \\ for (;c;) return 2;
2150 \\ return 3;
2151 \\}
2152 , &[_][]const u8{
2153 \\pub fn for_none_bool(a: c_int, b: f32, c: ?*c_void) c_int {
2154 \\ while (a != 0) return 0;
2155 \\ while (b != 0) return 1;
2156 \\ while (c != null) return 2;
2157 \\ return 3;
2158 \\}
2159 });
2160
2161 cases.addC("implicit casts",2098 cases.addC("implicit casts",
2162 \\#include <stdbool.h>2099 \\#include <stdbool.h>
2163 \\2100 \\
...@@ -2675,4 +2612,130 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -2675,4 +2612,130 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
2675 \\ return array[index];2612 \\ return array[index];
2676 \\}2613 \\}
2677 });2614 });
2615
2616 cases.addC("logical and, logical or",
2617 \\int max(int a, int b) {
2618 \\ if (a < b || a == b)
2619 \\ return b;
2620 \\ if (a >= b && a == b)
2621 \\ return a;
2622 \\ return a;
2623 \\}
2624 , &[_][]const u8{
2625 \\pub export fn max(a: c_int, b: c_int) c_int {
2626 \\ if ((a < b) or (a == b)) return b;
2627 \\ if ((a >= b) and (a == b)) return a;
2628 \\ return a;
2629 \\}
2630 });
2631
2632 cases.addC("if statement",
2633 \\int max(int a, int b) {
2634 \\ if (a < b)
2635 \\ return b;
2636 \\
2637 \\ if (a < b)
2638 \\ return b;
2639 \\ else
2640 \\ return a;
2641 \\
2642 \\ if (a < b) ; else ;
2643 \\}
2644 , &[_][]const u8{
2645 \\pub export fn max(a: c_int, b: c_int) c_int {
2646 \\ if (a < b) return b;
2647 \\ if (a < b) return b else return a;
2648 \\ if (a < b) {} else {}
2649 \\}
2650 });
2651
2652 cases.addC("logical and, logical or, on non-bool values", // Note this gets cut off by extra C symbols being injected in middle: `pub const Foo = enum_Foo;`
2653 \\enum Foo {
2654 \\ FooA,
2655 \\ FooB,
2656 \\ FooC,
2657 \\};
2658 \\int and_or_non_bool(int a, float b, void *c) {
2659 \\ enum Foo d = FooA;
2660 \\ int e = (a && b);
2661 \\ int f = (b && c);
2662 \\ int g = (a && c);
2663 \\ int h = (a || b);
2664 \\ int i = (b || c);
2665 \\ int j = (a || c);
2666 \\ int k = (a || d);
2667 \\ int l = (d && b);
2668 \\ int m = (c || d);
2669 \\ return (((((((e + f) + g) + h) + i) + j) + k) + l) + m;
2670 \\}
2671 , &[_][]const u8{
2672 \\pub const FooA = enum_Foo.A;
2673 \\pub const FooB = enum_Foo.B;
2674 \\pub const FooC = enum_Foo.C;
2675 \\pub const enum_Foo = extern enum {
2676 \\ A,
2677 \\ B,
2678 \\ C,
2679 \\};
2680 \\pub export fn and_or_non_bool(a: c_int, b: f32, c: ?*c_void) c_int {
2681 \\ var d: enum_Foo = @as(enum_Foo, FooA);
2682 \\ var e: c_int = (a != 0) and (b != 0);
2683 \\ var f: c_int = (b != 0) and (c != null);
2684 \\ var g: c_int = (a != 0) and (c != null);
2685 \\ var h: c_int = (a != 0) or (b != 0);
2686 \\ var i: c_int = (b != 0) or (c != null);
2687 \\ var j: c_int = (a != 0) or (c != null);
2688 \\ var k: c_int = (a != 0) or (@as(c_uint, d) != @bitCast(enum_Foo, @as(@TagType(enum_Foo), 0)));
2689 \\ var l: c_int = (@as(c_uint, d) != @bitCast(enum_Foo, @as(@TagType(enum_Foo), 0))) and (b != 0);
2690 \\ var m: c_int = (c != null) or (@as(c_uint, d) != @bitCast(enum_Foo, @as(@TagType(enum_Foo), 0)));
2691 \\ return (((((((e + f) + g) + h) + i) + j) + k) + l) + m;
2692 \\}
2693 });
2694
2695 cases.add("variable name shadowing",
2696 \\int foo(void) {
2697 \\ int x = 1;
2698 \\ {
2699 \\ int x = 2;
2700 \\ x += 1;
2701 \\ }
2702 \\ return x;
2703 \\}
2704 , &[_][]const u8{
2705 \\pub fn foo() c_int {
2706 \\ var x: c_int = 1;
2707 \\ {
2708 \\ var x_0: c_int = 2;
2709 \\ x_0 += 1;
2710 \\ }
2711 \\ return x;
2712 \\}
2713 });
2714
2715 cases.add("if on non-bool",
2716 \\enum SomeEnum { A, B, C };
2717 \\int if_none_bool(int a, float b, void *c, enum SomeEnum d) {
2718 \\ if (a) return 0;
2719 \\ if (b) return 1;
2720 \\ if (c) return 2;
2721 \\ if (d) return 3;
2722 \\ return 4;
2723 \\}
2724 , &[_][]const u8{
2725 \\pub const A = enum_SomeEnum.A;
2726 \\pub const B = enum_SomeEnum.B;
2727 \\pub const C = enum_SomeEnum.C;
2728 \\pub const enum_SomeEnum = extern enum {
2729 \\ A,
2730 \\ B,
2731 \\ C,
2732 \\};
2733 \\pub fn if_none_bool(a: c_int, b: f32, c: ?*c_void, d: enum_SomeEnum) c_int {
2734 \\ if (a != 0) return 0;
2735 \\ if (b != 0) return 1;
2736 \\ if (c != null) return 2;
2737 \\ if (d != @bitCast(enum_SomeEnum, @as(@TagType(enum_SomeEnum), 0))) return 3;
2738 \\ return 4;
2739 \\}
2740 });
2678}2741}