translate-c-2 add missing casts

This commit is contained in:
Vexu 2019-12-19 21:30:51 +02:00
parent 61482be153
commit b7f18164f9
No known key found for this signature in database
GPG Key ID: 59AEB8936E16A6AC
2 changed files with 145 additions and 46 deletions

View File

@ -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)}),
}
}

View File

@ -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));
\\}
});
}