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
804804pub extern fn ZigClangType_isVoidType(self: ?*const struct_ZigClangType) bool;
805805pub extern fn ZigClangType_isRecordType(self: ?*const struct_ZigClangType) bool;
806806pub extern fn ZigClangType_isArrayType(self: ?*const struct_ZigClangType) bool;
807pub extern fn ZigClangType_isBooleanType(self: ?*const struct_ZigClangType) bool;
807808pub extern fn ZigClangType_getTypeClassName(self: *const struct_ZigClangType) [*:0]const u8;
808809pub extern fn ZigClangType_getAsArrayTypeUnsafe(self: *const ZigClangType) *const ZigClangArrayType;
809810pub 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)
12731273 try transExprCoercing(rp, scope, expr, .used, .r_value)
12741274 else
12751275 try transCreateNodeUndefinedLiteral(c);
1276 if (isBoolRes(init_node)) {
1276 if (!qualTypeIsBoolean(qual_type) and isBoolRes(init_node)) {
12771277 const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt");
12781278 try builtin_node.params.push(init_node);
12791279 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
......@@ -1339,9 +1339,13 @@ fn transImplicitCastExpr(
13391339 return transCreateNodeInfixOp(rp, scope, &ptr_to_int.base, .BangEqual, op_token, rhs_node, result_used, false);
13401340 },
13411341 .IntegralToBoolean => {
1342 // val != 0
13431342 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
13451349 const op_token = try appendToken(rp.c, .BangEqual, "!=");
13461350 const rhs_node = try transCreateNodeInt(rp.c, 0);
13471351 return transCreateNodeInfixOp(rp, scope, node, .BangEqual, op_token, rhs_node, result_used, false);
......@@ -1397,6 +1401,10 @@ fn transBoolExpr(
13971401 }
13981402}
13991403
1404fn exprIsBooleanType(expr: *const ZigClangExpr) bool {
1405 return qualTypeIsBoolean(ZigClangExpr_getType(expr));
1406}
1407
14001408fn isBoolRes(res: *ast.Node) bool {
14011409 switch (res.id) {
14021410 .InfixOp => switch (@fieldParentPtr(ast.Node.InfixOp, "base", res).op) {
......@@ -1726,6 +1734,14 @@ fn transCCast(
17261734 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
17271735 return &builtin_node.base;
17281736 }
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 }
17291745 if (ZigClangQualType_getTypeClass(ZigClangQualType_getCanonicalType(dst_type)) == .Enum) {
17301746 const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@intToEnum");
17311747 try builtin_node.params.push(try transQualType(rp, dst_type, loc));
......@@ -3040,6 +3056,10 @@ fn qualTypeIsPtr(qt: ZigClangQualType) bool {
30403056 return ZigClangType_getTypeClass(qualTypeCanon(qt)) == .Pointer;
30413057}
30423058
3059fn qualTypeIsBoolean(qt: ZigClangQualType) bool {
3060 return ZigClangType_isBooleanType(qualTypeCanon(qt));
3061}
3062
30433063fn qualTypeIntBitWidth(rp: RestorePoint, qt: ZigClangQualType, source_loc: ZigClangSourceLocation) !u32 {
30443064 const ty = ZigClangQualType_getTypePtr(qt);
30453065
......@@ -3316,7 +3336,7 @@ fn transCreateNodeAssign(
33163336 const lhs_node = try transExpr(rp, scope, lhs, .used, .l_value);
33173337 const eq_token = try appendToken(rp.c, .Equal, "=");
33183338 var rhs_node = try transExprCoercing(rp, scope, rhs, .used, .r_value);
3319 if (isBoolRes(rhs_node)) {
3339 if (!exprIsBooleanType(lhs) and isBoolRes(rhs_node)) {
33203340 const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt");
33213341 try builtin_node.params.push(rhs_node);
33223342 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
......@@ -3341,7 +3361,7 @@ fn transCreateNodeAssign(
33413361 const node = try transCreateNodeVarDecl(rp.c, false, true, tmp);
33423362 node.eq_token = try appendToken(rp.c, .Equal, "=");
33433363 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)) {
33453365 const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt");
33463366 try builtin_node.params.push(rhs_node);
33473367 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
src/zig_clang.cpp+5
......@@ -1809,6 +1809,11 @@ ZigClangQualType ZigClangType_getPointeeType(const ZigClangType *self) {
18091809 return bitcast(casted->getPointeeType());
18101810}
18111811
1812bool ZigClangType_isBooleanType(const ZigClangType *self) {
1813 auto casted = reinterpret_cast<const clang::Type *>(self);
1814 return casted->isBooleanType();
1815}
1816
18121817bool ZigClangType_isVoidType(const ZigClangType *self) {
18131818 auto casted = reinterpret_cast<const clang::Type *>(self);
18141819 return casted->isVoidType();
src/zig_clang.h+1
......@@ -931,6 +931,7 @@ ZIG_EXTERN_C bool ZigClangQualType_isRestrictQualified(struct ZigClangQualType);
931931
932932ZIG_EXTERN_C enum ZigClangTypeClass ZigClangType_getTypeClass(const struct ZigClangType *self);
933933ZIG_EXTERN_C struct ZigClangQualType ZigClangType_getPointeeType(const struct ZigClangType *self);
934ZIG_EXTERN_C bool ZigClangType_isBooleanType(const struct ZigClangType *self);
934935ZIG_EXTERN_C bool ZigClangType_isVoidType(const struct ZigClangType *self);
935936ZIG_EXTERN_C bool ZigClangType_isArrayType(const struct ZigClangType *self);
936937ZIG_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 {
24182418 \\pub export fn c() void {}
24192419 \\pub fn foo() void {}
24202420 });
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 });
24212438}