authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-08-13 16:06:42+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-08-13 18:40:14+03:00
log13e472aa2a8113df6417c09727297a6106127f8e
tree86dd8d4836f87b048d509a5ceb0685d448bfef4c
parentc5368ba20c79b62d658c71033df9aeb7aa6e4581
signature Commit is signed but in an unrecognized format.

translate-c: add return if one is needed


5 files changed, 86 insertions(+), 22 deletions(-)

lib/std/hash/auto_hash.zig+1-1
...@@ -129,7 +129,7 @@ pub fn hash(hasher: anytype, key: anytype, comptime strat: HashStrategy) void {...@@ -129,7 +129,7 @@ pub fn hash(hasher: anytype, key: anytype, comptime strat: HashStrategy) void {
129 }129 }
130 },130 },
131131
132 .Union => |info| blk: {132 .Union => |info| {
133 if (info.tag_type) |tag_type| {133 if (info.tag_type) |tag_type| {
134 const tag = meta.activeTag(key);134 const tag = meta.activeTag(key);
135 const s = hash(hasher, tag, strat);135 const s = hash(hasher, tag, strat);
src-self-hosted/Module.zig+2-2
...@@ -2798,7 +2798,7 @@ pub fn floatAdd(self: *Module, scope: *Scope, float_type: Type, src: usize, lhs:...@@ -2798,7 +2798,7 @@ pub fn floatAdd(self: *Module, scope: *Scope, float_type: Type, src: usize, lhs:
2798 val_payload.* = .{ .val = lhs_val + rhs_val };2798 val_payload.* = .{ .val = lhs_val + rhs_val };
2799 break :blk &val_payload.base;2799 break :blk &val_payload.base;
2800 },2800 },
2801 128 => blk: {2801 128 => {
2802 return self.fail(scope, src, "TODO Implement addition for big floats", .{});2802 return self.fail(scope, src, "TODO Implement addition for big floats", .{});
2803 },2803 },
2804 else => unreachable,2804 else => unreachable,
...@@ -2832,7 +2832,7 @@ pub fn floatSub(self: *Module, scope: *Scope, float_type: Type, src: usize, lhs:...@@ -2832,7 +2832,7 @@ pub fn floatSub(self: *Module, scope: *Scope, float_type: Type, src: usize, lhs:
2832 val_payload.* = .{ .val = lhs_val - rhs_val };2832 val_payload.* = .{ .val = lhs_val - rhs_val };
2833 break :blk &val_payload.base;2833 break :blk &val_payload.base;
2834 },2834 },
2835 128 => blk: {2835 128 => {
2836 return self.fail(scope, src, "TODO Implement substraction for big floats", .{});2836 return self.fail(scope, src, "TODO Implement substraction for big floats", .{});
2837 },2837 },
2838 else => unreachable,2838 else => unreachable,
src-self-hosted/translate_c.zig+40
...@@ -628,6 +628,46 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {...@@ -628,6 +628,46 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {
628 error.UnsupportedType,628 error.UnsupportedType,
629 => return failDecl(c, fn_decl_loc, fn_name, "unable to translate function", .{}),629 => return failDecl(c, fn_decl_loc, fn_name, "unable to translate function", .{}),
630 };630 };
631 // add return statement if the function didn't have one
632 blk: {
633 const fn_ty = @ptrCast(*const ZigClangFunctionType, fn_type);
634
635 if (ZigClangFunctionType_getNoReturnAttr(fn_ty)) break :blk;
636 const return_qt = ZigClangFunctionType_getReturnType(fn_ty);
637 if (isCVoid(return_qt)) break :blk;
638
639 if (block_scope.statements.items.len > 0) {
640 var last = block_scope.statements.items[block_scope.statements.items.len - 1];
641 while (true) {
642 switch (last.tag) {
643 .Block => {
644 const stmts = last.castTag(.Block).?.statements();
645 if (stmts.len == 0) break;
646
647 last = stmts[stmts.len - 1];
648 },
649 // no extra return needed
650 .Return => break :blk,
651 else => break,
652 }
653 }
654 }
655
656 const return_expr = try ast.Node.ControlFlowExpression.create(rp.c.arena, .{
657 .ltoken = try appendToken(rp.c, .Keyword_return, "return"),
658 .tag = .Return,
659 }, .{
660 .rhs = transZeroInitExpr(rp, scope, fn_decl_loc, ZigClangQualType_getTypePtr(return_qt)) catch |err| switch (err) {
661 error.OutOfMemory => |e| return e,
662 error.UnsupportedTranslation,
663 error.UnsupportedType,
664 => return failDecl(c, fn_decl_loc, fn_name, "unable to create a return value for function", .{}),
665 },
666 });
667 _ = try appendToken(rp.c, .Semicolon, ";");
668 try block_scope.statements.append(&return_expr.base);
669 }
670
631 const body_node = try block_scope.complete(rp.c);671 const body_node = try block_scope.complete(rp.c);
632 proto_node.setTrailer("body_node", &body_node.base);672 proto_node.setTrailer("body_node", &body_node.base);
633 return addTopLevelDecl(c, fn_name, &proto_node.base);673 return addTopLevelDecl(c, fn_name, &proto_node.base);
test/run_translated_c.zig-1
...@@ -15,7 +15,6 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void {...@@ -15,7 +15,6 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void {
15 \\ }15 \\ }
16 \\ if (s0 != 1) abort();16 \\ if (s0 != 1) abort();
17 \\ if (s1 != 10) abort();17 \\ if (s1 != 10) abort();
18 \\ return 0;
19 \\}18 \\}
20 , "");19 , "");
2120
test/translate_c.zig+43-18
...@@ -3,12 +3,33 @@ const std = @import("std");...@@ -3,12 +3,33 @@ const std = @import("std");
3const CrossTarget = std.zig.CrossTarget;3const CrossTarget = std.zig.CrossTarget;
44
5pub fn addCases(cases: *tests.TranslateCContext) void {5pub fn addCases(cases: *tests.TranslateCContext) void {
6 cases.add("missing return stmt",
7 \\int foo() {}
8 \\int bar() {
9 \\ int a = 2;
10 \\}
11 \\int baz() {
12 \\ return 0;
13 \\}
14 , &[_][]const u8{
15 \\pub export fn foo() c_int {
16 \\ return 0;
17 \\}
18 \\pub export fn bar() c_int {
19 \\ var a: c_int = 2;
20 \\ return 0;
21 \\}
22 \\pub export fn baz() c_int {
23 \\ return 0;
24 \\}
25 });
26
6 cases.add("alignof",27 cases.add("alignof",
7 \\int main() {28 \\void main() {
8 \\ int a = _Alignof(int);29 \\ int a = _Alignof(int);
9 \\}30 \\}
10 , &[_][]const u8{31 , &[_][]const u8{
11 \\pub export fn main() c_int {32 \\pub export fn main() void {
12 \\ var a: c_int = @bitCast(c_int, @truncate(c_uint, @alignOf(c_int)));33 \\ var a: c_int = @bitCast(c_int, @truncate(c_uint, @alignOf(c_int)));
13 \\}34 \\}
14 });35 });
...@@ -539,6 +560,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -539,6 +560,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
539 \\ c = (a * b);560 \\ c = (a * b);
540 \\ c = @divTrunc(a, b);561 \\ c = @divTrunc(a, b);
541 \\ c = @rem(a, b);562 \\ c = @rem(a, b);
563 \\ return 0;
542 \\}564 \\}
543 \\pub export fn u() c_uint {565 \\pub export fn u() c_uint {
544 \\ var a: c_uint = undefined;566 \\ var a: c_uint = undefined;
...@@ -549,6 +571,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -549,6 +571,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
549 \\ c = (a *% b);571 \\ c = (a *% b);
550 \\ c = (a / b);572 \\ c = (a / b);
551 \\ c = (a % b);573 \\ c = (a % b);
574 \\ return 0;
552 \\}575 \\}
553 });576 });
554577
...@@ -1596,13 +1619,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1596,13 +1619,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1596 });1619 });
15971620
1598 cases.add("worst-case assign",1621 cases.add("worst-case assign",
1599 \\int foo() {1622 \\void foo() {
1600 \\ int a;1623 \\ int a;
1601 \\ int b;1624 \\ int b;
1602 \\ a = b = 2;1625 \\ a = b = 2;
1603 \\}1626 \\}
1604 , &[_][]const u8{1627 , &[_][]const u8{
1605 \\pub export fn foo() c_int {1628 \\pub export fn foo() void {
1606 \\ var a: c_int = undefined;1629 \\ var a: c_int = undefined;
1607 \\ var b: c_int = undefined;1630 \\ var b: c_int = undefined;
1608 \\ a = blk: {1631 \\ a = blk: {
...@@ -1650,11 +1673,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1650,11 +1673,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1650 \\ a = 7;1673 \\ a = 7;
1651 \\ if (!true) break;1674 \\ if (!true) break;
1652 \\ }1675 \\ }
1676 \\ return 0;
1653 \\}1677 \\}
1654 });1678 });
16551679
1656 cases.add("for loops",1680 cases.add("for loops",
1657 \\int foo() {1681 \\void foo() {
1658 \\ for (int i = 2, b = 4; i + 2; i = 2) {1682 \\ for (int i = 2, b = 4; i + 2; i = 2) {
1659 \\ int a = 2;1683 \\ int a = 2;
1660 \\ a = 6, 5, 7;1684 \\ a = 6, 5, 7;
...@@ -1662,7 +1686,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1662,7 +1686,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1662 \\ char i = 2;1686 \\ char i = 2;
1663 \\}1687 \\}
1664 , &[_][]const u8{1688 , &[_][]const u8{
1665 \\pub export fn foo() c_int {1689 \\pub export fn foo() void {
1666 \\ {1690 \\ {
1667 \\ var i: c_int = 2;1691 \\ var i: c_int = 2;
1668 \\ var b: c_int = 4;1692 \\ var b: c_int = 4;
...@@ -1712,7 +1736,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1712,7 +1736,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1712 });1736 });
17131737
1714 cases.add("switch on int",1738 cases.add("switch on int",
1715 \\int switch_fn(int i) {1739 \\void switch_fn(int i) {
1716 \\ int res = 0;1740 \\ int res = 0;
1717 \\ switch (i) {1741 \\ switch (i) {
1718 \\ case 0:1742 \\ case 0:
...@@ -1727,7 +1751,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1727,7 +1751,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1727 \\ }1751 \\ }
1728 \\}1752 \\}
1729 , &[_][]const u8{1753 , &[_][]const u8{
1730 \\pub export fn switch_fn(arg_i: c_int) c_int {1754 \\pub export fn switch_fn(arg_i: c_int) void {
1731 \\ var i = arg_i;1755 \\ var i = arg_i;
1732 \\ var res: c_int = 0;1756 \\ var res: c_int = 0;
1733 \\ @"switch": {1757 \\ @"switch": {
...@@ -1787,13 +1811,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1787,13 +1811,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1787 });1811 });
17881812
1789 cases.add("assign",1813 cases.add("assign",
1790 \\int max(int a) {1814 \\void max(int a) {
1791 \\ int tmp;1815 \\ int tmp;
1792 \\ tmp = a;1816 \\ tmp = a;
1793 \\ a = tmp;1817 \\ a = tmp;
1794 \\}1818 \\}
1795 , &[_][]const u8{1819 , &[_][]const u8{
1796 \\pub export fn max(arg_a: c_int) c_int {1820 \\pub export fn max(arg_a: c_int) void {
1797 \\ var a = arg_a;1821 \\ var a = arg_a;
1798 \\ var tmp: c_int = undefined;1822 \\ var tmp: c_int = undefined;
1799 \\ tmp = a;1823 \\ tmp = a;
...@@ -2082,7 +2106,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -2082,7 +2106,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
2082 \\ int b;2106 \\ int b;
2083 \\}a;2107 \\}a;
2084 \\float b = 2.0f;2108 \\float b = 2.0f;
2085 \\int foo(void) {2109 \\void foo(void) {
2086 \\ struct Foo *c;2110 \\ struct Foo *c;
2087 \\ a.b;2111 \\ a.b;
2088 \\ c->b;2112 \\ c->b;
...@@ -2093,7 +2117,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -2093,7 +2117,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
2093 \\};2117 \\};
2094 \\pub extern var a: struct_Foo;2118 \\pub extern var a: struct_Foo;
2095 \\pub export var b: f32 = 2;2119 \\pub export var b: f32 = 2;
2096 \\pub export fn foo() c_int {2120 \\pub export fn foo() void {
2097 \\ var c: [*c]struct_Foo = undefined;2121 \\ var c: [*c]struct_Foo = undefined;
2098 \\ _ = a.b;2122 \\ _ = a.b;
2099 \\ _ = c.*.b;2123 \\ _ = c.*.b;
...@@ -2204,11 +2228,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -2204,11 +2228,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
2204 \\ if (a < b) return b;2228 \\ if (a < b) return b;
2205 \\ if (a < b) return b else return a;2229 \\ if (a < b) return b else return a;
2206 \\ if (a < b) {} else {}2230 \\ if (a < b) {} else {}
2231 \\ return 0;
2207 \\}2232 \\}
2208 });2233 });
22092234
2210 cases.add("if statements",2235 cases.add("if statements",
2211 \\int foo() {2236 \\void foo() {
2212 \\ if (2) {2237 \\ if (2) {
2213 \\ int a = 2;2238 \\ int a = 2;
2214 \\ }2239 \\ }
...@@ -2217,7 +2242,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -2217,7 +2242,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
2217 \\ }2242 \\ }
2218 \\}2243 \\}
2219 , &[_][]const u8{2244 , &[_][]const u8{
2220 \\pub export fn foo() c_int {2245 \\pub export fn foo() void {
2221 \\ if (true) {2246 \\ if (true) {
2222 \\ var a: c_int = 2;2247 \\ var a: c_int = 2;
2223 \\ }2248 \\ }
...@@ -2811,12 +2836,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -2811,12 +2836,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
2811 });2836 });
28122837
2813 cases.add("arg name aliasing decl which comes after",2838 cases.add("arg name aliasing decl which comes after",
2814 \\int foo(int bar) {2839 \\void foo(int bar) {
2815 \\ bar = 2;2840 \\ bar = 2;
2816 \\}2841 \\}
2817 \\int bar = 4;2842 \\int bar = 4;
2818 , &[_][]const u8{2843 , &[_][]const u8{
2819 \\pub export fn foo(arg_bar_1: c_int) c_int {2844 \\pub export fn foo(arg_bar_1: c_int) void {
2820 \\ var bar_1 = arg_bar_1;2845 \\ var bar_1 = arg_bar_1;
2821 \\ bar_1 = 2;2846 \\ bar_1 = 2;
2822 \\}2847 \\}
...@@ -2824,12 +2849,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -2824,12 +2849,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
2824 });2849 });
28252850
2826 cases.add("arg name aliasing macro which comes after",2851 cases.add("arg name aliasing macro which comes after",
2827 \\int foo(int bar) {2852 \\void foo(int bar) {
2828 \\ bar = 2;2853 \\ bar = 2;
2829 \\}2854 \\}
2830 \\#define bar 42855 \\#define bar 4
2831 , &[_][]const u8{2856 , &[_][]const u8{
2832 \\pub export fn foo(arg_bar_1: c_int) c_int {2857 \\pub export fn foo(arg_bar_1: c_int) void {
2833 \\ var bar_1 = arg_bar_1;2858 \\ var bar_1 = arg_bar_1;
2834 \\ bar_1 = 2;2859 \\ bar_1 = 2;
2835 \\}2860 \\}