Better _Bool translation
This commit is contained in:
parent
6ff70d3c31
commit
cd39f6df95
@ -804,6 +804,7 @@ pub extern fn ZigClangType_getPointeeType(self: ?*const struct_ZigClangType) str
|
|||||||
pub extern fn ZigClangType_isVoidType(self: ?*const struct_ZigClangType) bool;
|
pub extern fn ZigClangType_isVoidType(self: ?*const struct_ZigClangType) bool;
|
||||||
pub extern fn ZigClangType_isRecordType(self: ?*const struct_ZigClangType) bool;
|
pub extern fn ZigClangType_isRecordType(self: ?*const struct_ZigClangType) bool;
|
||||||
pub extern fn ZigClangType_isArrayType(self: ?*const struct_ZigClangType) bool;
|
pub extern fn ZigClangType_isArrayType(self: ?*const struct_ZigClangType) bool;
|
||||||
|
pub extern fn ZigClangType_isBooleanType(self: ?*const struct_ZigClangType) bool;
|
||||||
pub extern fn ZigClangType_getTypeClassName(self: *const struct_ZigClangType) [*:0]const u8;
|
pub extern fn ZigClangType_getTypeClassName(self: *const struct_ZigClangType) [*:0]const u8;
|
||||||
pub extern fn ZigClangType_getAsArrayTypeUnsafe(self: *const ZigClangType) *const ZigClangArrayType;
|
pub extern fn ZigClangType_getAsArrayTypeUnsafe(self: *const ZigClangType) *const ZigClangArrayType;
|
||||||
pub extern fn ZigClangType_getAsRecordType(self: *const ZigClangType) ?*const ZigClangRecordType;
|
pub extern fn ZigClangType_getAsRecordType(self: *const ZigClangType) ?*const ZigClangRecordType;
|
||||||
|
@ -1273,7 +1273,7 @@ fn transDeclStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangDeclStmt)
|
|||||||
try transExprCoercing(rp, scope, expr, .used, .r_value)
|
try transExprCoercing(rp, scope, expr, .used, .r_value)
|
||||||
else
|
else
|
||||||
try transCreateNodeUndefinedLiteral(c);
|
try transCreateNodeUndefinedLiteral(c);
|
||||||
if (isBoolRes(init_node)) {
|
if (!qualTypeIsBoolean(qual_type) and isBoolRes(init_node)) {
|
||||||
const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt");
|
const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt");
|
||||||
try builtin_node.params.push(init_node);
|
try builtin_node.params.push(init_node);
|
||||||
builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
|
builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
|
||||||
@ -1339,9 +1339,13 @@ fn transImplicitCastExpr(
|
|||||||
return transCreateNodeInfixOp(rp, scope, &ptr_to_int.base, .BangEqual, op_token, rhs_node, result_used, false);
|
return transCreateNodeInfixOp(rp, scope, &ptr_to_int.base, .BangEqual, op_token, rhs_node, result_used, false);
|
||||||
},
|
},
|
||||||
.IntegralToBoolean => {
|
.IntegralToBoolean => {
|
||||||
// val != 0
|
|
||||||
const node = try transExpr(rp, scope, sub_expr, .used, .r_value);
|
const node = try transExpr(rp, scope, sub_expr, .used, .r_value);
|
||||||
|
|
||||||
|
// The expression is already a boolean one, return it as-is
|
||||||
|
if (isBoolRes(node))
|
||||||
|
return node;
|
||||||
|
|
||||||
|
// val != 0
|
||||||
const op_token = try appendToken(rp.c, .BangEqual, "!=");
|
const op_token = try appendToken(rp.c, .BangEqual, "!=");
|
||||||
const rhs_node = try transCreateNodeInt(rp.c, 0);
|
const rhs_node = try transCreateNodeInt(rp.c, 0);
|
||||||
return transCreateNodeInfixOp(rp, scope, node, .BangEqual, op_token, rhs_node, result_used, false);
|
return transCreateNodeInfixOp(rp, scope, node, .BangEqual, op_token, rhs_node, result_used, false);
|
||||||
@ -1397,6 +1401,10 @@ fn transBoolExpr(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn exprIsBooleanType(expr: *const ZigClangExpr) bool {
|
||||||
|
return qualTypeIsBoolean(ZigClangExpr_getType(expr));
|
||||||
|
}
|
||||||
|
|
||||||
fn isBoolRes(res: *ast.Node) bool {
|
fn isBoolRes(res: *ast.Node) bool {
|
||||||
switch (res.id) {
|
switch (res.id) {
|
||||||
.InfixOp => switch (@fieldParentPtr(ast.Node.InfixOp, "base", res).op) {
|
.InfixOp => switch (@fieldParentPtr(ast.Node.InfixOp, "base", res).op) {
|
||||||
@ -1726,6 +1734,14 @@ fn transCCast(
|
|||||||
builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
|
builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
|
||||||
return &builtin_node.base;
|
return &builtin_node.base;
|
||||||
}
|
}
|
||||||
|
if (ZigClangType_isBooleanType(qualTypeCanon(src_type)) and
|
||||||
|
!ZigClangType_isBooleanType(qualTypeCanon(dst_type)))
|
||||||
|
{
|
||||||
|
const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt");
|
||||||
|
try builtin_node.params.push(expr);
|
||||||
|
builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
|
||||||
|
return &builtin_node.base;
|
||||||
|
}
|
||||||
if (ZigClangQualType_getTypeClass(ZigClangQualType_getCanonicalType(dst_type)) == .Enum) {
|
if (ZigClangQualType_getTypeClass(ZigClangQualType_getCanonicalType(dst_type)) == .Enum) {
|
||||||
const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@intToEnum");
|
const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@intToEnum");
|
||||||
try builtin_node.params.push(try transQualType(rp, dst_type, loc));
|
try builtin_node.params.push(try transQualType(rp, dst_type, loc));
|
||||||
@ -3040,6 +3056,10 @@ fn qualTypeIsPtr(qt: ZigClangQualType) bool {
|
|||||||
return ZigClangType_getTypeClass(qualTypeCanon(qt)) == .Pointer;
|
return ZigClangType_getTypeClass(qualTypeCanon(qt)) == .Pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn qualTypeIsBoolean(qt: ZigClangQualType) bool {
|
||||||
|
return ZigClangType_isBooleanType(qualTypeCanon(qt));
|
||||||
|
}
|
||||||
|
|
||||||
fn qualTypeIntBitWidth(rp: RestorePoint, qt: ZigClangQualType, source_loc: ZigClangSourceLocation) !u32 {
|
fn qualTypeIntBitWidth(rp: RestorePoint, qt: ZigClangQualType, source_loc: ZigClangSourceLocation) !u32 {
|
||||||
const ty = ZigClangQualType_getTypePtr(qt);
|
const ty = ZigClangQualType_getTypePtr(qt);
|
||||||
|
|
||||||
@ -3316,7 +3336,7 @@ fn transCreateNodeAssign(
|
|||||||
const lhs_node = try transExpr(rp, scope, lhs, .used, .l_value);
|
const lhs_node = try transExpr(rp, scope, lhs, .used, .l_value);
|
||||||
const eq_token = try appendToken(rp.c, .Equal, "=");
|
const eq_token = try appendToken(rp.c, .Equal, "=");
|
||||||
var rhs_node = try transExprCoercing(rp, scope, rhs, .used, .r_value);
|
var rhs_node = try transExprCoercing(rp, scope, rhs, .used, .r_value);
|
||||||
if (isBoolRes(rhs_node)) {
|
if (!exprIsBooleanType(lhs) and isBoolRes(rhs_node)) {
|
||||||
const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt");
|
const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt");
|
||||||
try builtin_node.params.push(rhs_node);
|
try builtin_node.params.push(rhs_node);
|
||||||
builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
|
builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
|
||||||
@ -3341,7 +3361,7 @@ fn transCreateNodeAssign(
|
|||||||
const node = try transCreateNodeVarDecl(rp.c, false, true, tmp);
|
const node = try transCreateNodeVarDecl(rp.c, false, true, tmp);
|
||||||
node.eq_token = try appendToken(rp.c, .Equal, "=");
|
node.eq_token = try appendToken(rp.c, .Equal, "=");
|
||||||
var rhs_node = try transExpr(rp, &block_scope.base, rhs, .used, .r_value);
|
var rhs_node = try transExpr(rp, &block_scope.base, rhs, .used, .r_value);
|
||||||
if (isBoolRes(rhs_node)) {
|
if (!exprIsBooleanType(lhs) and isBoolRes(rhs_node)) {
|
||||||
const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt");
|
const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt");
|
||||||
try builtin_node.params.push(rhs_node);
|
try builtin_node.params.push(rhs_node);
|
||||||
builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
|
builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
|
||||||
|
@ -1809,6 +1809,11 @@ ZigClangQualType ZigClangType_getPointeeType(const ZigClangType *self) {
|
|||||||
return bitcast(casted->getPointeeType());
|
return bitcast(casted->getPointeeType());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ZigClangType_isBooleanType(const ZigClangType *self) {
|
||||||
|
auto casted = reinterpret_cast<const clang::Type *>(self);
|
||||||
|
return casted->isBooleanType();
|
||||||
|
}
|
||||||
|
|
||||||
bool ZigClangType_isVoidType(const ZigClangType *self) {
|
bool ZigClangType_isVoidType(const ZigClangType *self) {
|
||||||
auto casted = reinterpret_cast<const clang::Type *>(self);
|
auto casted = reinterpret_cast<const clang::Type *>(self);
|
||||||
return casted->isVoidType();
|
return casted->isVoidType();
|
||||||
|
@ -931,6 +931,7 @@ ZIG_EXTERN_C bool ZigClangQualType_isRestrictQualified(struct ZigClangQualType);
|
|||||||
|
|
||||||
ZIG_EXTERN_C enum ZigClangTypeClass ZigClangType_getTypeClass(const struct ZigClangType *self);
|
ZIG_EXTERN_C enum ZigClangTypeClass ZigClangType_getTypeClass(const struct ZigClangType *self);
|
||||||
ZIG_EXTERN_C struct ZigClangQualType ZigClangType_getPointeeType(const struct ZigClangType *self);
|
ZIG_EXTERN_C struct ZigClangQualType ZigClangType_getPointeeType(const struct ZigClangType *self);
|
||||||
|
ZIG_EXTERN_C bool ZigClangType_isBooleanType(const struct ZigClangType *self);
|
||||||
ZIG_EXTERN_C bool ZigClangType_isVoidType(const struct ZigClangType *self);
|
ZIG_EXTERN_C bool ZigClangType_isVoidType(const struct ZigClangType *self);
|
||||||
ZIG_EXTERN_C bool ZigClangType_isArrayType(const struct ZigClangType *self);
|
ZIG_EXTERN_C bool ZigClangType_isArrayType(const struct ZigClangType *self);
|
||||||
ZIG_EXTERN_C bool ZigClangType_isRecordType(const struct ZigClangType *self);
|
ZIG_EXTERN_C bool ZigClangType_isRecordType(const struct ZigClangType *self);
|
||||||
|
@ -2418,4 +2418,21 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
|||||||
\\pub export fn c() void {}
|
\\pub export fn c() void {}
|
||||||
\\pub fn foo() void {}
|
\\pub fn foo() void {}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
cases.add("handling of _Bool type",
|
||||||
|
\\_Bool foo(_Bool x) {
|
||||||
|
\\ _Bool a = x != 1;
|
||||||
|
\\ _Bool b = a != 0;
|
||||||
|
\\ _Bool c = foo;
|
||||||
|
\\ return foo(c != b);
|
||||||
|
\\}
|
||||||
|
, &[_][]const u8{
|
||||||
|
\\pub export fn foo(arg_x: bool) bool {
|
||||||
|
\\ var x = arg_x;
|
||||||
|
\\ var a: bool = (@boolToInt(x) != @as(c_int, 1));
|
||||||
|
\\ var b: bool = (@boolToInt(a) != @as(c_int, 0));
|
||||||
|
\\ var c: bool = @ptrToInt(foo) != 0;
|
||||||
|
\\ return foo((@boolToInt(c) != @boolToInt(b)));
|
||||||
|
\\}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user