authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-01-05 20:02:28+01:00
committergravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-01-06 00:12:18+01:00
logcd39f6df957886f4b40a30b3bd02148abcac16b0
treeb62dc4be0e13f3866bfe85768ccd642386bb90b9
parent6ff70d3c31607abfab7b0641bb903859972a6a8b

Better _Bool translation


5 files changed, 48 insertions(+), 4 deletions(-)

src-self-hosted/clang.zig+1
...@@ -804,6 +804,7 @@ pub extern fn ZigClangType_getPointeeType(self: ?*const struct_ZigClangType) str...@@ -804,6 +804,7 @@ pub extern fn ZigClangType_getPointeeType(self: ?*const struct_ZigClangType) str
804pub extern fn ZigClangType_isVoidType(self: ?*const struct_ZigClangType) bool;804pub extern fn ZigClangType_isVoidType(self: ?*const struct_ZigClangType) bool;
805pub extern fn ZigClangType_isRecordType(self: ?*const struct_ZigClangType) bool;805pub extern fn ZigClangType_isRecordType(self: ?*const struct_ZigClangType) bool;
806pub extern fn ZigClangType_isArrayType(self: ?*const struct_ZigClangType) bool;806pub extern fn ZigClangType_isArrayType(self: ?*const struct_ZigClangType) bool;
807pub extern fn ZigClangType_isBooleanType(self: ?*const struct_ZigClangType) bool;
807pub extern fn ZigClangType_getTypeClassName(self: *const struct_ZigClangType) [*:0]const u8;808pub extern fn ZigClangType_getTypeClassName(self: *const struct_ZigClangType) [*:0]const u8;
808pub extern fn ZigClangType_getAsArrayTypeUnsafe(self: *const ZigClangType) *const ZigClangArrayType;809pub extern fn ZigClangType_getAsArrayTypeUnsafe(self: *const ZigClangType) *const ZigClangArrayType;
809pub extern fn ZigClangType_getAsRecordType(self: *const ZigClangType) ?*const ZigClangRecordType;810pub extern fn ZigClangType_getAsRecordType(self: *const ZigClangType) ?*const ZigClangRecordType;
src-self-hosted/translate_c.zig+24-4
...@@ -1273,7 +1273,7 @@ fn transDeclStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangDeclStmt)...@@ -1273,7 +1273,7 @@ fn transDeclStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangDeclStmt)
1273 try transExprCoercing(rp, scope, expr, .used, .r_value)1273 try transExprCoercing(rp, scope, expr, .used, .r_value)
1274 else1274 else
1275 try transCreateNodeUndefinedLiteral(c);1275 try transCreateNodeUndefinedLiteral(c);
1276 if (isBoolRes(init_node)) {1276 if (!qualTypeIsBoolean(qual_type) and isBoolRes(init_node)) {
1277 const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt");1277 const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt");
1278 try builtin_node.params.push(init_node);1278 try builtin_node.params.push(init_node);
1279 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");1279 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
...@@ -1339,9 +1339,13 @@ fn transImplicitCastExpr(...@@ -1339,9 +1339,13 @@ fn transImplicitCastExpr(
1339 return transCreateNodeInfixOp(rp, scope, &ptr_to_int.base, .BangEqual, op_token, rhs_node, result_used, false);1339 return transCreateNodeInfixOp(rp, scope, &ptr_to_int.base, .BangEqual, op_token, rhs_node, result_used, false);
1340 },1340 },
1341 .IntegralToBoolean => {1341 .IntegralToBoolean => {
1342 // val != 0
1343 const node = try transExpr(rp, scope, sub_expr, .used, .r_value);1342 const node = try transExpr(rp, scope, sub_expr, .used, .r_value);
13441343
1344 // The expression is already a boolean one, return it as-is
1345 if (isBoolRes(node))
1346 return node;
1347
1348 // val != 0
1345 const op_token = try appendToken(rp.c, .BangEqual, "!=");1349 const op_token = try appendToken(rp.c, .BangEqual, "!=");
1346 const rhs_node = try transCreateNodeInt(rp.c, 0);1350 const rhs_node = try transCreateNodeInt(rp.c, 0);
1347 return transCreateNodeInfixOp(rp, scope, node, .BangEqual, op_token, rhs_node, result_used, false);1351 return transCreateNodeInfixOp(rp, scope, node, .BangEqual, op_token, rhs_node, result_used, false);
...@@ -1397,6 +1401,10 @@ fn transBoolExpr(...@@ -1397,6 +1401,10 @@ fn transBoolExpr(
1397 }1401 }
1398}1402}
13991403
1404fn exprIsBooleanType(expr: *const ZigClangExpr) bool {
1405 return qualTypeIsBoolean(ZigClangExpr_getType(expr));
1406}
1407
1400fn isBoolRes(res: *ast.Node) bool {1408fn isBoolRes(res: *ast.Node) bool {
1401 switch (res.id) {1409 switch (res.id) {
1402 .InfixOp => switch (@fieldParentPtr(ast.Node.InfixOp, "base", res).op) {1410 .InfixOp => switch (@fieldParentPtr(ast.Node.InfixOp, "base", res).op) {
...@@ -1726,6 +1734,14 @@ fn transCCast(...@@ -1726,6 +1734,14 @@ fn transCCast(
1726 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");1734 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
1727 return &builtin_node.base;1735 return &builtin_node.base;
1728 }1736 }
1737 if (ZigClangType_isBooleanType(qualTypeCanon(src_type)) and
1738 !ZigClangType_isBooleanType(qualTypeCanon(dst_type)))
1739 {
1740 const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt");
1741 try builtin_node.params.push(expr);
1742 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
1743 return &builtin_node.base;
1744 }
1729 if (ZigClangQualType_getTypeClass(ZigClangQualType_getCanonicalType(dst_type)) == .Enum) {1745 if (ZigClangQualType_getTypeClass(ZigClangQualType_getCanonicalType(dst_type)) == .Enum) {
1730 const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@intToEnum");1746 const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@intToEnum");
1731 try builtin_node.params.push(try transQualType(rp, dst_type, loc));1747 try builtin_node.params.push(try transQualType(rp, dst_type, loc));
...@@ -3040,6 +3056,10 @@ fn qualTypeIsPtr(qt: ZigClangQualType) bool {...@@ -3040,6 +3056,10 @@ fn qualTypeIsPtr(qt: ZigClangQualType) bool {
3040 return ZigClangType_getTypeClass(qualTypeCanon(qt)) == .Pointer;3056 return ZigClangType_getTypeClass(qualTypeCanon(qt)) == .Pointer;
3041}3057}
30423058
3059fn qualTypeIsBoolean(qt: ZigClangQualType) bool {
3060 return ZigClangType_isBooleanType(qualTypeCanon(qt));
3061}
3062
3043fn qualTypeIntBitWidth(rp: RestorePoint, qt: ZigClangQualType, source_loc: ZigClangSourceLocation) !u32 {3063fn qualTypeIntBitWidth(rp: RestorePoint, qt: ZigClangQualType, source_loc: ZigClangSourceLocation) !u32 {
3044 const ty = ZigClangQualType_getTypePtr(qt);3064 const ty = ZigClangQualType_getTypePtr(qt);
30453065
...@@ -3316,7 +3336,7 @@ fn transCreateNodeAssign(...@@ -3316,7 +3336,7 @@ fn transCreateNodeAssign(
3316 const lhs_node = try transExpr(rp, scope, lhs, .used, .l_value);3336 const lhs_node = try transExpr(rp, scope, lhs, .used, .l_value);
3317 const eq_token = try appendToken(rp.c, .Equal, "=");3337 const eq_token = try appendToken(rp.c, .Equal, "=");
3318 var rhs_node = try transExprCoercing(rp, scope, rhs, .used, .r_value);3338 var rhs_node = try transExprCoercing(rp, scope, rhs, .used, .r_value);
3319 if (isBoolRes(rhs_node)) {3339 if (!exprIsBooleanType(lhs) and isBoolRes(rhs_node)) {
3320 const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt");3340 const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt");
3321 try builtin_node.params.push(rhs_node);3341 try builtin_node.params.push(rhs_node);
3322 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");3342 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
...@@ -3341,7 +3361,7 @@ fn transCreateNodeAssign(...@@ -3341,7 +3361,7 @@ fn transCreateNodeAssign(
3341 const node = try transCreateNodeVarDecl(rp.c, false, true, tmp);3361 const node = try transCreateNodeVarDecl(rp.c, false, true, tmp);
3342 node.eq_token = try appendToken(rp.c, .Equal, "=");3362 node.eq_token = try appendToken(rp.c, .Equal, "=");
3343 var rhs_node = try transExpr(rp, &block_scope.base, rhs, .used, .r_value);3363 var rhs_node = try transExpr(rp, &block_scope.base, rhs, .used, .r_value);
3344 if (isBoolRes(rhs_node)) {3364 if (!exprIsBooleanType(lhs) and isBoolRes(rhs_node)) {
3345 const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt");3365 const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt");
3346 try builtin_node.params.push(rhs_node);3366 try builtin_node.params.push(rhs_node);
3347 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");3367 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
src/zig_clang.cpp+5
...@@ -1809,6 +1809,11 @@ ZigClangQualType ZigClangType_getPointeeType(const ZigClangType *self) {...@@ -1809,6 +1809,11 @@ ZigClangQualType ZigClangType_getPointeeType(const ZigClangType *self) {
1809 return bitcast(casted->getPointeeType());1809 return bitcast(casted->getPointeeType());
1810}1810}
18111811
1812bool ZigClangType_isBooleanType(const ZigClangType *self) {
1813 auto casted = reinterpret_cast<const clang::Type *>(self);
1814 return casted->isBooleanType();
1815}
1816
1812bool ZigClangType_isVoidType(const ZigClangType *self) {1817bool ZigClangType_isVoidType(const ZigClangType *self) {
1813 auto casted = reinterpret_cast<const clang::Type *>(self);1818 auto casted = reinterpret_cast<const clang::Type *>(self);
1814 return casted->isVoidType();1819 return casted->isVoidType();
src/zig_clang.h+1
...@@ -931,6 +931,7 @@ ZIG_EXTERN_C bool ZigClangQualType_isRestrictQualified(struct ZigClangQualType);...@@ -931,6 +931,7 @@ ZIG_EXTERN_C bool ZigClangQualType_isRestrictQualified(struct ZigClangQualType);
931931
932ZIG_EXTERN_C enum ZigClangTypeClass ZigClangType_getTypeClass(const struct ZigClangType *self);932ZIG_EXTERN_C enum ZigClangTypeClass ZigClangType_getTypeClass(const struct ZigClangType *self);
933ZIG_EXTERN_C struct ZigClangQualType ZigClangType_getPointeeType(const struct ZigClangType *self);933ZIG_EXTERN_C struct ZigClangQualType ZigClangType_getPointeeType(const struct ZigClangType *self);
934ZIG_EXTERN_C bool ZigClangType_isBooleanType(const struct ZigClangType *self);
934ZIG_EXTERN_C bool ZigClangType_isVoidType(const struct ZigClangType *self);935ZIG_EXTERN_C bool ZigClangType_isVoidType(const struct ZigClangType *self);
935ZIG_EXTERN_C bool ZigClangType_isArrayType(const struct ZigClangType *self);936ZIG_EXTERN_C bool ZigClangType_isArrayType(const struct ZigClangType *self);
936ZIG_EXTERN_C bool ZigClangType_isRecordType(const struct ZigClangType *self);937ZIG_EXTERN_C bool ZigClangType_isRecordType(const struct ZigClangType *self);
test/translate_c.zig+17
...@@ -2418,4 +2418,21 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -2418,4 +2418,21 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
2418 \\pub export fn c() void {}2418 \\pub export fn c() void {}
2419 \\pub fn foo() void {}2419 \\pub fn foo() void {}
2420 });2420 });
2421
2422 cases.add("handling of _Bool type",
2423 \\_Bool foo(_Bool x) {
2424 \\ _Bool a = x != 1;
2425 \\ _Bool b = a != 0;
2426 \\ _Bool c = foo;
2427 \\ return foo(c != b);
2428 \\}
2429 , &[_][]const u8{
2430 \\pub export fn foo(arg_x: bool) bool {
2431 \\ var x = arg_x;
2432 \\ var a: bool = (@boolToInt(x) != @as(c_int, 1));
2433 \\ var b: bool = (@boolToInt(a) != @as(c_int, 0));
2434 \\ var c: bool = @ptrToInt(foo) != 0;
2435 \\ return foo((@boolToInt(c) != @boolToInt(b)));
2436 \\}
2437 });
2421}2438}