Commit b7f18164f9
Changed files (2)
src-self-hosted
test
src-self-hosted/translate_c.zig
@@ -1210,10 +1210,10 @@ fn transImplicitCastExpr(
const c = rp.c;
const sub_expr = ZigClangImplicitCastExpr_getSubExpr(expr);
const sub_expr_node = try transExpr(rp, scope, @ptrCast(*const ZigClangExpr, sub_expr), .used, .r_value);
+ const dest_type = getExprQualType(c, @ptrCast(*const ZigClangExpr, expr));
+ const src_type = getExprQualType(c, sub_expr);
switch (ZigClangImplicitCastExpr_getCastKind(expr)) {
.BitCast, .FloatingCast, .FloatingToIntegral, .IntegralToFloating, .IntegralCast => {
- const dest_type = getExprQualType(c, @ptrCast(*const ZigClangExpr, expr));
- const src_type = getExprQualType(c, sub_expr);
return transCCast(rp, scope, ZigClangImplicitCastExpr_getBeginLoc(expr), dest_type, src_type, sub_expr_node);
},
.LValueToRValue, .NoOp, .FunctionToPointerDecay, .ArrayToPointerDecay => {
@@ -1222,6 +1222,47 @@ fn transImplicitCastExpr(
.NullToPointer => {
return try transCreateNodeNullLiteral(rp.c);
},
+ .PointerToBoolean => {
+ // @ptrToInt(val) != 0
+ const ptr_to_int = try transCreateNodeBuiltinFnCall(rp.c, "@ptrToInt");
+ try ptr_to_int.params.push(try transExpr(rp, scope, sub_expr, .used, .r_value));
+ ptr_to_int.rparen_token = try appendToken(rp.c, .RParen, ")");
+
+ const op_token = try appendToken(rp.c, .BangEqual, "!=");
+ const rhs_node = try transCreateNodeInt(rp.c, 0);
+ return transCreateNodeInfixOp(rp, scope, &ptr_to_int.base, .BangEqual, op_token, rhs_node, result_used, false);
+ },
+ .IntegralToBoolean => {
+ // val != 0
+ const node = try transExpr(rp, scope, sub_expr, .used, .r_value);
+
+ const op_token = try appendToken(rp.c, .BangEqual, "!=");
+ const rhs_node = try transCreateNodeInt(rp.c, 0);
+ return transCreateNodeInfixOp(rp, scope, node, .BangEqual, op_token, rhs_node, result_used, false);
+ },
+ .PointerToIntegral => {
+ // @intCast(dest_type, @ptrToInt(val))
+ const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@intCast");
+ try cast_node.params.push(try transQualType(rp, dest_type, ZigClangImplicitCastExpr_getBeginLoc(expr)));
+ _ = try appendToken(rp.c, .Comma, ",");
+
+ const ptr_to_int = try transCreateNodeBuiltinFnCall(rp.c, "@ptrToInt");
+ try ptr_to_int.params.push(try transExpr(rp, scope, sub_expr, .used, .r_value));
+ ptr_to_int.rparen_token = try appendToken(rp.c, .RParen, ")");
+ try cast_node.params.push(&ptr_to_int.base);
+ cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
+ return maybeSuppressResult(rp, scope, result_used, &cast_node.base);
+ },
+ .IntegralToPointer => {
+ // @intToPtr(dest_type, val)
+ const int_to_ptr = try transCreateNodeBuiltinFnCall(rp.c, "@intToPtr");
+ try int_to_ptr.params.push(try transQualType(rp, dest_type, ZigClangImplicitCastExpr_getBeginLoc(expr)));
+ _ = try appendToken(rp.c, .Comma, ",");
+
+ try int_to_ptr.params.push(try transExpr(rp, scope, sub_expr, .used, .r_value));
+ int_to_ptr.rparen_token = try appendToken(rp.c, .RParen, ")");
+ return maybeSuppressResult(rp, scope, result_used, &int_to_ptr.base);
+ },
else => |kind| return revertAndWarn(
rp,
error.UnsupportedTranslation,
@@ -2224,6 +2265,9 @@ fn transUnaryOperator(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangUnar
op_node.rhs = try transBoolExpr(rp, scope, op_expr, .used, .r_value, true);
return &op_node.base;
},
+ .Extension => {
+ return transExpr(rp, scope, ZigClangUnaryOperator_getSubExpr(stmt), used, .l_value);
+ },
else => return revertAndWarn(rp, error.UnsupportedTranslation, ZigClangUnaryOperator_getBeginLoc(stmt), "unsupported C translation {}", .{ZigClangUnaryOperator_getOpcode(stmt)}),
}
}
test/translate_c.zig
@@ -819,6 +819,16 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
+ cases.addC("__extension__ cast",
+ \\int foo(void) {
+ \\ return __extension__ 1;
+ \\}
+ , &[_][]const u8{
+ \\pub export fn foo() c_int {
+ \\ return 1;
+ \\}
+ });
+
/////////////// Cases that pass for only stage2 ////////////////
cases.add_2("Parameterless function prototypes",
@@ -2031,43 +2041,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- /////////////// Cases for only stage1 which are TODO items for stage2 ////////////////
-
- cases.add("macro defines string literal with hex",
- \\#define FOO "aoeu\xab derp"
- \\#define FOO2 "aoeu\x0007a derp"
- \\#define FOO_CHAR '\xfF'
- , &[_][]const u8{
- \\pub const FOO = "aoeu\xab derp";
- ,
- \\pub const FOO2 = "aoeuz derp";
- ,
- \\pub const FOO_CHAR = 255;
- });
-
- cases.add("macro defines string literal with octal",
- \\#define FOO "aoeu\023 derp"
- \\#define FOO2 "aoeu\0234 derp"
- \\#define FOO_CHAR '\077'
- , &[_][]const u8{
- \\pub const FOO = "aoeu\x13 derp";
- ,
- \\pub const FOO2 = "aoeu\x134 derp";
- ,
- \\pub const FOO_CHAR = 63;
- });
-
- cases.addC("__extension__ cast",
- \\int foo(void) {
- \\ return __extension__ 1;
- \\}
- , &[_][]const u8{
- \\pub export fn foo() c_int {
- \\ return 1;
- \\}
- });
-
- cases.addC("implicit casts",
+ cases.add_2("implicit casts",
\\#include <stdbool.h>
\\
\\void fn_int(int x);
@@ -2103,25 +2077,51 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub extern fn fn_bool(x: bool) void;
\\pub extern fn fn_ptr(x: ?*c_void) void;
\\pub export fn call(q: c_int) void {
- \\ fn_int(@floatToInt(c_int, 3.000000));
- \\ fn_int(@floatToInt(c_int, 3.000000));
- \\ fn_int(@floatToInt(c_int, 3.000000));
+ \\ fn_int(@floatToInt(c_int, 3));
+ \\ fn_int(@floatToInt(c_int, 3));
+ \\ fn_int(@floatToInt(c_int, 3));
\\ fn_int(1094861636);
\\ fn_f32(@intToFloat(f32, 3));
\\ fn_f64(@intToFloat(f64, 3));
\\ fn_char(@as(u8, '3'));
\\ fn_char(@as(u8, '\x01'));
\\ fn_char(@as(u8, 0));
- \\ fn_f32(3.000000);
- \\ fn_f64(3.000000);
- \\ fn_bool(true);
- \\ fn_bool(false);
+ \\ fn_f32(3);
+ \\ fn_f64(3);
+ \\ fn_bool(123 != 0);
+ \\ fn_bool(0 != 0);
\\ fn_bool(@ptrToInt(&fn_int) != 0);
\\ fn_int(@intCast(c_int, @ptrToInt(&fn_int)));
\\ fn_ptr(@intToPtr(?*c_void, 42));
\\}
});
+ /////////////// Cases for only stage1 which are TODO items for stage2 ////////////////
+
+ cases.add("macro defines string literal with hex",
+ \\#define FOO "aoeu\xab derp"
+ \\#define FOO2 "aoeu\x0007a derp"
+ \\#define FOO_CHAR '\xfF'
+ , &[_][]const u8{
+ \\pub const FOO = "aoeu\xab derp";
+ ,
+ \\pub const FOO2 = "aoeuz derp";
+ ,
+ \\pub const FOO_CHAR = 255;
+ });
+
+ cases.add("macro defines string literal with octal",
+ \\#define FOO "aoeu\023 derp"
+ \\#define FOO2 "aoeu\0234 derp"
+ \\#define FOO_CHAR '\077'
+ , &[_][]const u8{
+ \\pub const FOO = "aoeu\x13 derp";
+ ,
+ \\pub const FOO2 = "aoeu\x134 derp";
+ ,
+ \\pub const FOO_CHAR = 63;
+ });
+
if (builtin.os != builtin.Os.windows) {
// sysv_abi not currently supported on windows
cases.add("Macro qualified functions",
@@ -2990,4 +2990,59 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ });
\\}
});
+
+ cases.addC("implicit casts",
+ \\#include <stdbool.h>
+ \\
+ \\void fn_int(int x);
+ \\void fn_f32(float x);
+ \\void fn_f64(double x);
+ \\void fn_char(char x);
+ \\void fn_bool(bool x);
+ \\void fn_ptr(void *x);
+ \\
+ \\void call(int q) {
+ \\ fn_int(3.0f);
+ \\ fn_int(3.0);
+ \\ fn_int(3.0L);
+ \\ fn_int('ABCD');
+ \\ fn_f32(3);
+ \\ fn_f64(3);
+ \\ fn_char('3');
+ \\ fn_char('\x1');
+ \\ fn_char(0);
+ \\ fn_f32(3.0f);
+ \\ fn_f64(3.0);
+ \\ fn_bool(123);
+ \\ fn_bool(0);
+ \\ fn_bool(&fn_int);
+ \\ fn_int(&fn_int);
+ \\ fn_ptr(42);
+ \\}
+ , &[_][]const u8{
+ \\pub extern fn fn_int(x: c_int) void;
+ \\pub extern fn fn_f32(x: f32) void;
+ \\pub extern fn fn_f64(x: f64) void;
+ \\pub extern fn fn_char(x: u8) void;
+ \\pub extern fn fn_bool(x: bool) void;
+ \\pub extern fn fn_ptr(x: ?*c_void) void;
+ \\pub export fn call(q: c_int) void {
+ \\ fn_int(@floatToInt(c_int, 3.000000));
+ \\ fn_int(@floatToInt(c_int, 3.000000));
+ \\ fn_int(@floatToInt(c_int, 3.000000));
+ \\ fn_int(1094861636);
+ \\ fn_f32(@intToFloat(f32, 3));
+ \\ fn_f64(@intToFloat(f64, 3));
+ \\ fn_char(@as(u8, '3'));
+ \\ fn_char(@as(u8, '\x01'));
+ \\ fn_char(@as(u8, 0));
+ \\ fn_f32(3.000000);
+ \\ fn_f64(3.000000);
+ \\ fn_bool(true);
+ \\ fn_bool(false);
+ \\ fn_bool(@ptrToInt(&fn_int) != 0);
+ \\ fn_int(@intCast(c_int, @ptrToInt(&fn_int)));
+ \\ fn_ptr(@intToPtr(?*c_void, 42));
+ \\}
+ });
}