| ... | @@ -769,6 +769,56 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -769,6 +769,56 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 769 | \\} | 769 | \\} |
| 770 | }); | 770 | }); |
| 771 | | 771 | |
| | 772 | cases.addC_both("normal deref", |
| | 773 | \\void foo(int *x) { |
| | 774 | \\ *x = 1; |
| | 775 | \\} |
| | 776 | , &[_][]const u8{ |
| | 777 | \\pub export fn foo(x: [*c]c_int) void { |
| | 778 | \\ x.?.* = 1; |
| | 779 | \\} |
| | 780 | }); |
| | 781 | |
| | 782 | cases.addC_both("address of operator", |
| | 783 | \\int foo(void) { |
| | 784 | \\ int x = 1234; |
| | 785 | \\ int *ptr = &x; |
| | 786 | \\ return *ptr; |
| | 787 | \\} |
| | 788 | , &[_][]const u8{ |
| | 789 | \\pub export fn foo() c_int { |
| | 790 | \\ var x: c_int = 1234; |
| | 791 | \\ var ptr: [*c]c_int = &x; |
| | 792 | \\ return ptr.?.*; |
| | 793 | \\} |
| | 794 | }); |
| | 795 | |
| | 796 | cases.addC_both("bin not", |
| | 797 | \\int foo(int x) { |
| | 798 | \\ return ~x; |
| | 799 | \\} |
| | 800 | , &[_][]const u8{ |
| | 801 | \\pub export fn foo(x: c_int) c_int { |
| | 802 | \\ return ~x; |
| | 803 | \\} |
| | 804 | }); |
| | 805 | |
| | 806 | cases.addC_both("bool not", |
| | 807 | \\int foo(int a, float b, void *c) { |
| | 808 | \\ return !(a == 0); |
| | 809 | \\ return !a; |
| | 810 | \\ return !b; |
| | 811 | \\ return !c; |
| | 812 | \\} |
| | 813 | , &[_][]const u8{ |
| | 814 | \\pub export fn foo(a: c_int, b: f32, c: ?*c_void) c_int { |
| | 815 | \\ return !(a == 0); |
| | 816 | \\ return !(a != 0); |
| | 817 | \\ return !(b != 0); |
| | 818 | \\ return !(c != null); |
| | 819 | \\} |
| | 820 | }); |
| | 821 | |
| 772 | /////////////// Cases that pass for only stage2 //////////////// | 822 | /////////////// Cases that pass for only stage2 //////////////// |
| 773 | | 823 | |
| 774 | cases.add_2("Parameterless function prototypes", | 824 | cases.add_2("Parameterless function prototypes", |
| ... | @@ -1664,9 +1714,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -1664,9 +1714,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1664 | \\} | 1714 | \\} |
| 1665 | }); | 1715 | }); |
| 1666 | | 1716 | |
| 1667 | /////////////// Cases for only stage1 which are TODO items for stage2 //////////////// | 1717 | cases.add_2("simple data types", |
| 1668 | | | |
| 1669 | cases.addAllowWarnings("simple data types", | | |
| 1670 | \\#include <stdint.h> | 1718 | \\#include <stdint.h> |
| 1671 | \\int foo(char a, unsigned char b, signed char c); | 1719 | \\int foo(char a, unsigned char b, signed char c); |
| 1672 | \\int foo(char a, unsigned char b, signed char c); // test a duplicate prototype | 1720 | \\int foo(char a, unsigned char b, signed char c); // test a duplicate prototype |
| ... | @@ -1674,22 +1722,72 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -1674,22 +1722,72 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1674 | \\void baz(int8_t a, int16_t b, int32_t c, int64_t d); | 1722 | \\void baz(int8_t a, int16_t b, int32_t c, int64_t d); |
| 1675 | , &[_][]const u8{ | 1723 | , &[_][]const u8{ |
| 1676 | \\pub extern fn foo(a: u8, b: u8, c: i8) c_int; | 1724 | \\pub extern fn foo(a: u8, b: u8, c: i8) c_int; |
| 1677 | , | | |
| 1678 | \\pub extern fn bar(a: u8, b: u16, c: u32, d: u64) void; | 1725 | \\pub extern fn bar(a: u8, b: u16, c: u32, d: u64) void; |
| 1679 | , | | |
| 1680 | \\pub extern fn baz(a: i8, b: i16, c: i32, d: i64) void; | 1726 | \\pub extern fn baz(a: i8, b: i16, c: i32, d: i64) void; |
| 1681 | }); | 1727 | }); |
| 1682 | | 1728 | |
| 1683 | cases.addC("simple function", | 1729 | cases.add_2("simple function", |
| 1684 | \\int abs(int a) { | 1730 | \\int abs(int a) { |
| 1685 | \\ return a < 0 ? -a : a; | 1731 | \\ return a < 0 ? -a : a; |
| 1686 | \\} | 1732 | \\} |
| 1687 | , &[_][]const u8{ | 1733 | , &[_][]const u8{ |
| 1688 | \\export fn abs(a: c_int) c_int { | 1734 | \\pub export fn abs(a: c_int) c_int { |
| 1689 | \\ return if (a < 0) -a else a; | 1735 | \\ return if ((a < 0)) -a else a; |
| | 1736 | \\} |
| | 1737 | }); |
| | 1738 | |
| | 1739 | cases.add_2("post increment", |
| | 1740 | \\unsigned foo1(unsigned a) { |
| | 1741 | \\ a++; |
| | 1742 | \\ return a; |
| | 1743 | \\} |
| | 1744 | \\int foo2(int a) { |
| | 1745 | \\ a++; |
| | 1746 | \\ return a; |
| | 1747 | \\} |
| | 1748 | , &[_][]const u8{ |
| | 1749 | \\pub export fn foo1(a: c_uint) c_uint { |
| | 1750 | \\ a +%= 1; |
| | 1751 | \\ return a; |
| | 1752 | \\} |
| | 1753 | \\pub export fn foo2(a: c_int) c_int { |
| | 1754 | \\ a += 1; |
| | 1755 | \\ return a; |
| | 1756 | \\} |
| | 1757 | }); |
| | 1758 | |
| | 1759 | cases.add_2("deref function pointer", |
| | 1760 | \\void foo(void) {} |
| | 1761 | \\int baz(void) { return 0; } |
| | 1762 | \\void bar(void) { |
| | 1763 | \\ void(*f)(void) = foo; |
| | 1764 | \\ int(*b)(void) = baz; |
| | 1765 | \\ f(); |
| | 1766 | \\ (*(f))(); |
| | 1767 | \\ foo(); |
| | 1768 | \\ b(); |
| | 1769 | \\ (*(b))(); |
| | 1770 | \\ baz(); |
| | 1771 | \\} |
| | 1772 | , &[_][]const u8{ |
| | 1773 | \\pub export fn foo() void {} |
| | 1774 | \\pub export fn baz() c_int { |
| | 1775 | \\ return 0; |
| | 1776 | \\} |
| | 1777 | \\pub export fn bar() void { |
| | 1778 | \\ var f: ?extern fn () void = foo; |
| | 1779 | \\ var b: ?extern fn () c_int = baz; |
| | 1780 | \\ f.?(); |
| | 1781 | \\ (f).?(); |
| | 1782 | \\ foo(); |
| | 1783 | \\ _ = b.?(); |
| | 1784 | \\ _ = (b).?(); |
| | 1785 | \\ _ = baz(); |
| 1690 | \\} | 1786 | \\} |
| 1691 | }); | 1787 | }); |
| 1692 | | 1788 | |
| | 1789 | /////////////// Cases for only stage1 which are TODO items for stage2 //////////////// |
| | 1790 | |
| 1693 | cases.add("macro defines string literal with hex", | 1791 | cases.add("macro defines string literal with hex", |
| 1694 | \\#define FOO "aoeu\xab derp" | 1792 | \\#define FOO "aoeu\xab derp" |
| 1695 | \\#define FOO2 "aoeu\x0007a derp" | 1793 | \\#define FOO2 "aoeu\x0007a derp" |
| ... | @@ -1714,28 +1812,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -1714,28 +1812,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1714 | \\pub const FOO_CHAR = 63; | 1812 | \\pub const FOO_CHAR = 63; |
| 1715 | }); | 1813 | }); |
| 1716 | | 1814 | |
| 1717 | cases.addC("post increment", | | |
| 1718 | \\unsigned foo1(unsigned a) { | | |
| 1719 | \\ a++; | | |
| 1720 | \\ return a; | | |
| 1721 | \\} | | |
| 1722 | \\int foo2(int a) { | | |
| 1723 | \\ a++; | | |
| 1724 | \\ return a; | | |
| 1725 | \\} | | |
| 1726 | , &[_][]const u8{ | | |
| 1727 | \\pub export fn foo1(_arg_a: c_uint) c_uint { | | |
| 1728 | \\ var a = _arg_a; | | |
| 1729 | \\ a +%= 1; | | |
| 1730 | \\ return a; | | |
| 1731 | \\} | | |
| 1732 | \\pub export fn foo2(_arg_a: c_int) c_int { | | |
| 1733 | \\ var a = _arg_a; | | |
| 1734 | \\ a += 1; | | |
| 1735 | \\ return a; | | |
| 1736 | \\} | | |
| 1737 | }); | | |
| 1738 | | | |
| 1739 | cases.addC("shift right assign", | 1815 | cases.addC("shift right assign", |
| 1740 | \\int log2(unsigned a) { | 1816 | \\int log2(unsigned a) { |
| 1741 | \\ int i = 0; | 1817 | \\ int i = 0; |
| ... | @@ -1993,96 +2069,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -1993,96 +2069,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1993 | \\} | 2069 | \\} |
| 1994 | }); | 2070 | }); |
| 1995 | | 2071 | |
| 1996 | cases.addC("deref function pointer", | | |
| 1997 | \\void foo(void) {} | | |
| 1998 | \\int baz(void) { return 0; } | | |
| 1999 | \\void bar(void) { | | |
| 2000 | \\ void(*f)(void) = foo; | | |
| 2001 | \\ int(*b)(void) = baz; | | |
| 2002 | \\ f(); | | |
| 2003 | \\ (*(f))(); | | |
| 2004 | \\ foo(); | | |
| 2005 | \\ b(); | | |
| 2006 | \\ (*(b))(); | | |
| 2007 | \\ baz(); | | |
| 2008 | \\} | | |
| 2009 | , &[_][]const u8{ | | |
| 2010 | \\pub export fn foo() void {} | | |
| 2011 | \\pub export fn baz() c_int { | | |
| 2012 | \\ return 0; | | |
| 2013 | \\} | | |
| 2014 | \\pub export fn bar() void { | | |
| 2015 | \\ var f: ?extern fn () void = foo; | | |
| 2016 | \\ var b: ?extern fn () c_int = baz; | | |
| 2017 | \\ f.?(); | | |
| 2018 | \\ f.?(); | | |
| 2019 | \\ foo(); | | |
| 2020 | \\ _ = b.?(); | | |
| 2021 | \\ _ = b.?(); | | |
| 2022 | \\ _ = baz(); | | |
| 2023 | \\} | | |
| 2024 | }); | | |
| 2025 | | | |
| 2026 | cases.addC("normal deref", | | |
| 2027 | \\void foo(int *x) { | | |
| 2028 | \\ *x = 1; | | |
| 2029 | \\} | | |
| 2030 | , &[_][]const u8{ | | |
| 2031 | \\pub export fn foo(x: [*c]c_int) void { | | |
| 2032 | \\ x.?.* = 1; | | |
| 2033 | \\} | | |
| 2034 | }); | | |
| 2035 | | | |
| 2036 | cases.add("address of operator", | | |
| 2037 | \\int foo(void) { | | |
| 2038 | \\ int x = 1234; | | |
| 2039 | \\ int *ptr = &x; | | |
| 2040 | \\ return *ptr; | | |
| 2041 | \\} | | |
| 2042 | , &[_][]const u8{ | | |
| 2043 | \\pub fn foo() c_int { | | |
| 2044 | \\ var x: c_int = 1234; | | |
| 2045 | \\ var ptr: [*c]c_int = &x; | | |
| 2046 | \\ return ptr.?.*; | | |
| 2047 | \\} | | |
| 2048 | }); | | |
| 2049 | | | |
| 2050 | cases.add("bin not", | | |
| 2051 | \\int foo(int x) { | | |
| 2052 | \\ return ~x; | | |
| 2053 | \\} | | |
| 2054 | , &[_][]const u8{ | | |
| 2055 | \\pub fn foo(x: c_int) c_int { | | |
| 2056 | \\ return ~x; | | |
| 2057 | \\} | | |
| 2058 | }); | | |
| 2059 | | | |
| 2060 | cases.add("bool not", | | |
| 2061 | \\int foo(int a, float b, void *c) { | | |
| 2062 | \\ return !(a == 0); | | |
| 2063 | \\ return !a; | | |
| 2064 | \\ return !b; | | |
| 2065 | \\ return !c; | | |
| 2066 | \\} | | |
| 2067 | , &[_][]const u8{ | | |
| 2068 | \\pub fn foo(a: c_int, b: f32, c: ?*c_void) c_int { | | |
| 2069 | \\ return !(a == 0); | | |
| 2070 | \\ return !(a != 0); | | |
| 2071 | \\ return !(b != 0); | | |
| 2072 | \\ return !(c != null); | | |
| 2073 | \\} | | |
| 2074 | }); | | |
| 2075 | | | |
| 2076 | cases.add("primitive types included in defined symbols", | | |
| 2077 | \\int foo(int u32) { | | |
| 2078 | \\ return u32; | | |
| 2079 | \\} | | |
| 2080 | , &[_][]const u8{ | | |
| 2081 | \\pub fn foo(u32_0: c_int) c_int { | | |
| 2082 | \\ return u32_0; | | |
| 2083 | \\} | | |
| 2084 | }); | | |
| 2085 | | | |
| 2086 | cases.addC("implicit casts", | 2072 | cases.addC("implicit casts", |
| 2087 | \\#include <stdbool.h> | 2073 | \\#include <stdbool.h> |
| 2088 | \\ | 2074 | \\ |
| ... | @@ -2637,49 +2623,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -2637,49 +2623,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 2637 | \\} | 2623 | \\} |
| 2638 | }); | 2624 | }); |
| 2639 | | 2625 | |
| 2640 | cases.addC("logical and, logical or, on non-bool values", // Note this gets cut off by extra C symbols being injected in middle: `pub const Foo = enum_Foo;` | | |
| 2641 | \\enum Foo { | | |
| 2642 | \\ FooA, | | |
| 2643 | \\ FooB, | | |
| 2644 | \\ FooC, | | |
| 2645 | \\}; | | |
| 2646 | \\int and_or_non_bool(int a, float b, void *c) { | | |
| 2647 | \\ enum Foo d = FooA; | | |
| 2648 | \\ int e = (a && b); | | |
| 2649 | \\ int f = (b && c); | | |
| 2650 | \\ int g = (a && c); | | |
| 2651 | \\ int h = (a || b); | | |
| 2652 | \\ int i = (b || c); | | |
| 2653 | \\ int j = (a || c); | | |
| 2654 | \\ int k = (a || d); | | |
| 2655 | \\ int l = (d && b); | | |
| 2656 | \\ int m = (c || d); | | |
| 2657 | \\ return (((((((e + f) + g) + h) + i) + j) + k) + l) + m; | | |
| 2658 | \\} | | |
| 2659 | , &[_][]const u8{ | | |
| 2660 | \\pub const FooA = enum_Foo.A; | | |
| 2661 | \\pub const FooB = enum_Foo.B; | | |
| 2662 | \\pub const FooC = enum_Foo.C; | | |
| 2663 | \\pub const enum_Foo = extern enum { | | |
| 2664 | \\ A, | | |
| 2665 | \\ B, | | |
| 2666 | \\ C, | | |
| 2667 | \\}; | | |
| 2668 | \\pub export fn and_or_non_bool(a: c_int, b: f32, c: ?*c_void) c_int { | | |
| 2669 | \\ var d: enum_Foo = @as(enum_Foo, FooA); | | |
| 2670 | \\ var e: c_int = (a != 0) and (b != 0); | | |
| 2671 | \\ var f: c_int = (b != 0) and (c != null); | | |
| 2672 | \\ var g: c_int = (a != 0) and (c != null); | | |
| 2673 | \\ var h: c_int = (a != 0) or (b != 0); | | |
| 2674 | \\ var i: c_int = (b != 0) or (c != null); | | |
| 2675 | \\ var j: c_int = (a != 0) or (c != null); | | |
| 2676 | \\ var k: c_int = (a != 0) or (@as(c_uint, d) != @bitCast(enum_Foo, @as(@TagType(enum_Foo), 0))); | | |
| 2677 | \\ var l: c_int = (@as(c_uint, d) != @bitCast(enum_Foo, @as(@TagType(enum_Foo), 0))) and (b != 0); | | |
| 2678 | \\ var m: c_int = (c != null) or (@as(c_uint, d) != @bitCast(enum_Foo, @as(@TagType(enum_Foo), 0))); | | |
| 2679 | \\ return (((((((e + f) + g) + h) + i) + j) + k) + l) + m; | | |
| 2680 | \\} | | |
| 2681 | }); | | |
| 2682 | | | |
| 2683 | cases.add("variable name shadowing", | 2626 | cases.add("variable name shadowing", |
| 2684 | \\int foo(void) { | 2627 | \\int foo(void) { |
| 2685 | \\ int x = 1; | 2628 | \\ int x = 1; |
| ... | @@ -2726,4 +2669,80 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -2726,4 +2669,80 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 2726 | \\ return 4; | 2669 | \\ return 4; |
| 2727 | \\} | 2670 | \\} |
| 2728 | }); | 2671 | }); |
| | 2672 | |
| | 2673 | cases.addAllowWarnings("simple data types", |
| | 2674 | \\#include <stdint.h> |
| | 2675 | \\int foo(char a, unsigned char b, signed char c); |
| | 2676 | \\int foo(char a, unsigned char b, signed char c); // test a duplicate prototype |
| | 2677 | \\void bar(uint8_t a, uint16_t b, uint32_t c, uint64_t d); |
| | 2678 | \\void baz(int8_t a, int16_t b, int32_t c, int64_t d); |
| | 2679 | , &[_][]const u8{ |
| | 2680 | \\pub extern fn foo(a: u8, b: u8, c: i8) c_int; |
| | 2681 | , |
| | 2682 | \\pub extern fn bar(a: u8, b: u16, c: u32, d: u64) void; |
| | 2683 | , |
| | 2684 | \\pub extern fn baz(a: i8, b: i16, c: i32, d: i64) void; |
| | 2685 | }); |
| | 2686 | |
| | 2687 | cases.addC("simple function", |
| | 2688 | \\int abs(int a) { |
| | 2689 | \\ return a < 0 ? -a : a; |
| | 2690 | \\} |
| | 2691 | , &[_][]const u8{ |
| | 2692 | \\pub export fn abs(a: c_int) c_int { |
| | 2693 | \\ return if (a < 0) -a else a; |
| | 2694 | \\} |
| | 2695 | }); |
| | 2696 | |
| | 2697 | cases.addC("post increment", |
| | 2698 | \\unsigned foo1(unsigned a) { |
| | 2699 | \\ a++; |
| | 2700 | \\ return a; |
| | 2701 | \\} |
| | 2702 | \\int foo2(int a) { |
| | 2703 | \\ a++; |
| | 2704 | \\ return a; |
| | 2705 | \\} |
| | 2706 | , &[_][]const u8{ |
| | 2707 | \\pub export fn foo1(_arg_a: c_uint) c_uint { |
| | 2708 | \\ var a = _arg_a; |
| | 2709 | \\ a +%= 1; |
| | 2710 | \\ return a; |
| | 2711 | \\} |
| | 2712 | \\pub export fn foo2(_arg_a: c_int) c_int { |
| | 2713 | \\ var a = _arg_a; |
| | 2714 | \\ a += 1; |
| | 2715 | \\ return a; |
| | 2716 | \\} |
| | 2717 | }); |
| | 2718 | |
| | 2719 | cases.addC("deref function pointer", |
| | 2720 | \\void foo(void) {} |
| | 2721 | \\int baz(void) { return 0; } |
| | 2722 | \\void bar(void) { |
| | 2723 | \\ void(*f)(void) = foo; |
| | 2724 | \\ int(*b)(void) = baz; |
| | 2725 | \\ f(); |
| | 2726 | \\ (*(f))(); |
| | 2727 | \\ foo(); |
| | 2728 | \\ b(); |
| | 2729 | \\ (*(b))(); |
| | 2730 | \\ baz(); |
| | 2731 | \\} |
| | 2732 | , &[_][]const u8{ |
| | 2733 | \\pub export fn foo() void {} |
| | 2734 | \\pub export fn baz() c_int { |
| | 2735 | \\ return 0; |
| | 2736 | \\} |
| | 2737 | \\pub export fn bar() void { |
| | 2738 | \\ var f: ?extern fn () void = foo; |
| | 2739 | \\ var b: ?extern fn () c_int = baz; |
| | 2740 | \\ f.?(); |
| | 2741 | \\ f.?(); |
| | 2742 | \\ foo(); |
| | 2743 | \\ _ = b.?(); |
| | 2744 | \\ _ = b.?(); |
| | 2745 | \\ _ = baz(); |
| | 2746 | \\} |
| | 2747 | }); |
| 2729 | } | 2748 | } |