authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2019-12-19 21:30:51+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2019-12-19 21:30:51+02:00
logb7f18164f96f7e695d295c12c06fddf25803b08b
tree10e0a8fbac651efeab35a03dbdf9a5878f9d6240
parent61482be15380be22c8333ff4c6557108596efba2
signature Commit is signed but in an unrecognized format.

translate-c-2 add missing casts


2 files changed, 145 insertions(+), 46 deletions(-)

src-self-hosted/translate_c.zig+46-2
...@@ -1210,10 +1210,10 @@ fn transImplicitCastExpr(...@@ -1210,10 +1210,10 @@ fn transImplicitCastExpr(
1210 const c = rp.c;1210 const c = rp.c;
1211 const sub_expr = ZigClangImplicitCastExpr_getSubExpr(expr);1211 const sub_expr = ZigClangImplicitCastExpr_getSubExpr(expr);
1212 const sub_expr_node = try transExpr(rp, scope, @ptrCast(*const ZigClangExpr, sub_expr), .used, .r_value);1212 const sub_expr_node = try transExpr(rp, scope, @ptrCast(*const ZigClangExpr, sub_expr), .used, .r_value);
1213 const dest_type = getExprQualType(c, @ptrCast(*const ZigClangExpr, expr));
1214 const src_type = getExprQualType(c, sub_expr);
1213 switch (ZigClangImplicitCastExpr_getCastKind(expr)) {1215 switch (ZigClangImplicitCastExpr_getCastKind(expr)) {
1214 .BitCast, .FloatingCast, .FloatingToIntegral, .IntegralToFloating, .IntegralCast => {1216 .BitCast, .FloatingCast, .FloatingToIntegral, .IntegralToFloating, .IntegralCast => {
1215 const dest_type = getExprQualType(c, @ptrCast(*const ZigClangExpr, expr));
1216 const src_type = getExprQualType(c, sub_expr);
1217 return transCCast(rp, scope, ZigClangImplicitCastExpr_getBeginLoc(expr), dest_type, src_type, sub_expr_node);1217 return transCCast(rp, scope, ZigClangImplicitCastExpr_getBeginLoc(expr), dest_type, src_type, sub_expr_node);
1218 },1218 },
1219 .LValueToRValue, .NoOp, .FunctionToPointerDecay, .ArrayToPointerDecay => {1219 .LValueToRValue, .NoOp, .FunctionToPointerDecay, .ArrayToPointerDecay => {
...@@ -1222,6 +1222,47 @@ fn transImplicitCastExpr(...@@ -1222,6 +1222,47 @@ fn transImplicitCastExpr(
1222 .NullToPointer => {1222 .NullToPointer => {
1223 return try transCreateNodeNullLiteral(rp.c);1223 return try transCreateNodeNullLiteral(rp.c);
1224 },1224 },
1225 .PointerToBoolean => {
1226 // @ptrToInt(val) != 0
1227 const ptr_to_int = try transCreateNodeBuiltinFnCall(rp.c, "@ptrToInt");
1228 try ptr_to_int.params.push(try transExpr(rp, scope, sub_expr, .used, .r_value));
1229 ptr_to_int.rparen_token = try appendToken(rp.c, .RParen, ")");
1230
1231 const op_token = try appendToken(rp.c, .BangEqual, "!=");
1232 const rhs_node = try transCreateNodeInt(rp.c, 0);
1233 return transCreateNodeInfixOp(rp, scope, &ptr_to_int.base, .BangEqual, op_token, rhs_node, result_used, false);
1234 },
1235 .IntegralToBoolean => {
1236 // val != 0
1237 const node = try transExpr(rp, scope, sub_expr, .used, .r_value);
1238
1239 const op_token = try appendToken(rp.c, .BangEqual, "!=");
1240 const rhs_node = try transCreateNodeInt(rp.c, 0);
1241 return transCreateNodeInfixOp(rp, scope, node, .BangEqual, op_token, rhs_node, result_used, false);
1242 },
1243 .PointerToIntegral => {
1244 // @intCast(dest_type, @ptrToInt(val))
1245 const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@intCast");
1246 try cast_node.params.push(try transQualType(rp, dest_type, ZigClangImplicitCastExpr_getBeginLoc(expr)));
1247 _ = try appendToken(rp.c, .Comma, ",");
1248
1249 const ptr_to_int = try transCreateNodeBuiltinFnCall(rp.c, "@ptrToInt");
1250 try ptr_to_int.params.push(try transExpr(rp, scope, sub_expr, .used, .r_value));
1251 ptr_to_int.rparen_token = try appendToken(rp.c, .RParen, ")");
1252 try cast_node.params.push(&ptr_to_int.base);
1253 cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
1254 return maybeSuppressResult(rp, scope, result_used, &cast_node.base);
1255 },
1256 .IntegralToPointer => {
1257 // @intToPtr(dest_type, val)
1258 const int_to_ptr = try transCreateNodeBuiltinFnCall(rp.c, "@intToPtr");
1259 try int_to_ptr.params.push(try transQualType(rp, dest_type, ZigClangImplicitCastExpr_getBeginLoc(expr)));
1260 _ = try appendToken(rp.c, .Comma, ",");
1261
1262 try int_to_ptr.params.push(try transExpr(rp, scope, sub_expr, .used, .r_value));
1263 int_to_ptr.rparen_token = try appendToken(rp.c, .RParen, ")");
1264 return maybeSuppressResult(rp, scope, result_used, &int_to_ptr.base);
1265 },
1225 else => |kind| return revertAndWarn(1266 else => |kind| return revertAndWarn(
1226 rp,1267 rp,
1227 error.UnsupportedTranslation,1268 error.UnsupportedTranslation,
...@@ -2224,6 +2265,9 @@ fn transUnaryOperator(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangUnar...@@ -2224,6 +2265,9 @@ fn transUnaryOperator(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangUnar
2224 op_node.rhs = try transBoolExpr(rp, scope, op_expr, .used, .r_value, true);2265 op_node.rhs = try transBoolExpr(rp, scope, op_expr, .used, .r_value, true);
2225 return &op_node.base;2266 return &op_node.base;
2226 },2267 },
2268 .Extension => {
2269 return transExpr(rp, scope, ZigClangUnaryOperator_getSubExpr(stmt), used, .l_value);
2270 },
2227 else => return revertAndWarn(rp, error.UnsupportedTranslation, ZigClangUnaryOperator_getBeginLoc(stmt), "unsupported C translation {}", .{ZigClangUnaryOperator_getOpcode(stmt)}),2271 else => return revertAndWarn(rp, error.UnsupportedTranslation, ZigClangUnaryOperator_getBeginLoc(stmt), "unsupported C translation {}", .{ZigClangUnaryOperator_getOpcode(stmt)}),
2228 }2272 }
2229}2273}
test/translate_c.zig+99-44
...@@ -819,6 +819,16 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -819,6 +819,16 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
819 \\}819 \\}
820 });820 });
821821
822 cases.addC("__extension__ cast",
823 \\int foo(void) {
824 \\ return __extension__ 1;
825 \\}
826 , &[_][]const u8{
827 \\pub export fn foo() c_int {
828 \\ return 1;
829 \\}
830 });
831
822 /////////////// Cases that pass for only stage2 ////////////////832 /////////////// Cases that pass for only stage2 ////////////////
823833
824 cases.add_2("Parameterless function prototypes",834 cases.add_2("Parameterless function prototypes",
...@@ -2031,43 +2041,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -2031,43 +2041,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
2031 \\}2041 \\}
2032 });2042 });
20332043
2034 /////////////// Cases for only stage1 which are TODO items for stage2 ////////////////2044 cases.add_2("implicit casts",
2035
2036 cases.add("macro defines string literal with hex",
2037 \\#define FOO "aoeu\xab derp"
2038 \\#define FOO2 "aoeu\x0007a derp"
2039 \\#define FOO_CHAR '\xfF'
2040 , &[_][]const u8{
2041 \\pub const FOO = "aoeu\xab derp";
2042 ,
2043 \\pub const FOO2 = "aoeuz derp";
2044 ,
2045 \\pub const FOO_CHAR = 255;
2046 });
2047
2048 cases.add("macro defines string literal with octal",
2049 \\#define FOO "aoeu\023 derp"
2050 \\#define FOO2 "aoeu\0234 derp"
2051 \\#define FOO_CHAR '\077'
2052 , &[_][]const u8{
2053 \\pub const FOO = "aoeu\x13 derp";
2054 ,
2055 \\pub const FOO2 = "aoeu\x134 derp";
2056 ,
2057 \\pub const FOO_CHAR = 63;
2058 });
2059
2060 cases.addC("__extension__ cast",
2061 \\int foo(void) {
2062 \\ return __extension__ 1;
2063 \\}
2064 , &[_][]const u8{
2065 \\pub export fn foo() c_int {
2066 \\ return 1;
2067 \\}
2068 });
2069
2070 cases.addC("implicit casts",
2071 \\#include <stdbool.h>2045 \\#include <stdbool.h>
2072 \\2046 \\
2073 \\void fn_int(int x);2047 \\void fn_int(int x);
...@@ -2103,25 +2077,51 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -2103,25 +2077,51 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
2103 \\pub extern fn fn_bool(x: bool) void;2077 \\pub extern fn fn_bool(x: bool) void;
2104 \\pub extern fn fn_ptr(x: ?*c_void) void;2078 \\pub extern fn fn_ptr(x: ?*c_void) void;
2105 \\pub export fn call(q: c_int) void {2079 \\pub export fn call(q: c_int) void {
2106 \\ fn_int(@floatToInt(c_int, 3.000000));2080 \\ fn_int(@floatToInt(c_int, 3));
2107 \\ fn_int(@floatToInt(c_int, 3.000000));2081 \\ fn_int(@floatToInt(c_int, 3));
2108 \\ fn_int(@floatToInt(c_int, 3.000000));2082 \\ fn_int(@floatToInt(c_int, 3));
2109 \\ fn_int(1094861636);2083 \\ fn_int(1094861636);
2110 \\ fn_f32(@intToFloat(f32, 3));2084 \\ fn_f32(@intToFloat(f32, 3));
2111 \\ fn_f64(@intToFloat(f64, 3));2085 \\ fn_f64(@intToFloat(f64, 3));
2112 \\ fn_char(@as(u8, '3'));2086 \\ fn_char(@as(u8, '3'));
2113 \\ fn_char(@as(u8, '\x01'));2087 \\ fn_char(@as(u8, '\x01'));
2114 \\ fn_char(@as(u8, 0));2088 \\ fn_char(@as(u8, 0));
2115 \\ fn_f32(3.000000);2089 \\ fn_f32(3);
2116 \\ fn_f64(3.000000);2090 \\ fn_f64(3);
2117 \\ fn_bool(true);2091 \\ fn_bool(123 != 0);
2118 \\ fn_bool(false);2092 \\ fn_bool(0 != 0);
2119 \\ fn_bool(@ptrToInt(&fn_int) != 0);2093 \\ fn_bool(@ptrToInt(&fn_int) != 0);
2120 \\ fn_int(@intCast(c_int, @ptrToInt(&fn_int)));2094 \\ fn_int(@intCast(c_int, @ptrToInt(&fn_int)));
2121 \\ fn_ptr(@intToPtr(?*c_void, 42));2095 \\ fn_ptr(@intToPtr(?*c_void, 42));
2122 \\}2096 \\}
2123 });2097 });
21242098
2099 /////////////// Cases for only stage1 which are TODO items for stage2 ////////////////
2100
2101 cases.add("macro defines string literal with hex",
2102 \\#define FOO "aoeu\xab derp"
2103 \\#define FOO2 "aoeu\x0007a derp"
2104 \\#define FOO_CHAR '\xfF'
2105 , &[_][]const u8{
2106 \\pub const FOO = "aoeu\xab derp";
2107 ,
2108 \\pub const FOO2 = "aoeuz derp";
2109 ,
2110 \\pub const FOO_CHAR = 255;
2111 });
2112
2113 cases.add("macro defines string literal with octal",
2114 \\#define FOO "aoeu\023 derp"
2115 \\#define FOO2 "aoeu\0234 derp"
2116 \\#define FOO_CHAR '\077'
2117 , &[_][]const u8{
2118 \\pub const FOO = "aoeu\x13 derp";
2119 ,
2120 \\pub const FOO2 = "aoeu\x134 derp";
2121 ,
2122 \\pub const FOO_CHAR = 63;
2123 });
2124
2125 if (builtin.os != builtin.Os.windows) {2125 if (builtin.os != builtin.Os.windows) {
2126 // sysv_abi not currently supported on windows2126 // sysv_abi not currently supported on windows
2127 cases.add("Macro qualified functions",2127 cases.add("Macro qualified functions",
...@@ -2990,4 +2990,59 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -2990,4 +2990,59 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
2990 \\ });2990 \\ });
2991 \\}2991 \\}
2992 });2992 });
2993
2994 cases.addC("implicit casts",
2995 \\#include <stdbool.h>
2996 \\
2997 \\void fn_int(int x);
2998 \\void fn_f32(float x);
2999 \\void fn_f64(double x);
3000 \\void fn_char(char x);
3001 \\void fn_bool(bool x);
3002 \\void fn_ptr(void *x);
3003 \\
3004 \\void call(int q) {
3005 \\ fn_int(3.0f);
3006 \\ fn_int(3.0);
3007 \\ fn_int(3.0L);
3008 \\ fn_int('ABCD');
3009 \\ fn_f32(3);
3010 \\ fn_f64(3);
3011 \\ fn_char('3');
3012 \\ fn_char('\x1');
3013 \\ fn_char(0);
3014 \\ fn_f32(3.0f);
3015 \\ fn_f64(3.0);
3016 \\ fn_bool(123);
3017 \\ fn_bool(0);
3018 \\ fn_bool(&fn_int);
3019 \\ fn_int(&fn_int);
3020 \\ fn_ptr(42);
3021 \\}
3022 , &[_][]const u8{
3023 \\pub extern fn fn_int(x: c_int) void;
3024 \\pub extern fn fn_f32(x: f32) void;
3025 \\pub extern fn fn_f64(x: f64) void;
3026 \\pub extern fn fn_char(x: u8) void;
3027 \\pub extern fn fn_bool(x: bool) void;
3028 \\pub extern fn fn_ptr(x: ?*c_void) void;
3029 \\pub export fn call(q: c_int) void {
3030 \\ fn_int(@floatToInt(c_int, 3.000000));
3031 \\ fn_int(@floatToInt(c_int, 3.000000));
3032 \\ fn_int(@floatToInt(c_int, 3.000000));
3033 \\ fn_int(1094861636);
3034 \\ fn_f32(@intToFloat(f32, 3));
3035 \\ fn_f64(@intToFloat(f64, 3));
3036 \\ fn_char(@as(u8, '3'));
3037 \\ fn_char(@as(u8, '\x01'));
3038 \\ fn_char(@as(u8, 0));
3039 \\ fn_f32(3.000000);
3040 \\ fn_f64(3.000000);
3041 \\ fn_bool(true);
3042 \\ fn_bool(false);
3043 \\ fn_bool(@ptrToInt(&fn_int) != 0);
3044 \\ fn_int(@intCast(c_int, @ptrToInt(&fn_int)));
3045 \\ fn_ptr(@intToPtr(?*c_void, 42));
3046 \\}
3047 });
2993}3048}