mirror of
https://github.com/ziglang/zig.git
synced 2024-11-15 08:33:06 +00:00
translate-c-2 add missing casts
This commit is contained in:
parent
61482be153
commit
b7f18164f9
@ -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)}),
|
||||
}
|
||||
}
|
||||
|
@ -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));
|
||||
\\}
|
||||
});
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user