| ... | ... | @@ -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 | 822 | /////////////// Cases that pass for only stage2 //////////////// |
| 773 | 823 | |
| 774 | 824 | cases.add_2("Parameterless function prototypes", |
| ... | ... | @@ -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 //////////////// |
| 1668 | | |
| 1669 | | cases.addAllowWarnings("simple data types", |
| 1717 | cases.add_2("simple data types", |
| 1670 | 1718 | \\#include <stdint.h> |
| 1671 | 1719 | \\int foo(char a, unsigned char b, signed char c); |
| 1672 | 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 | 1722 | \\void baz(int8_t a, int16_t b, int32_t c, int64_t d); |
| 1675 | 1723 | , &[_][]const u8{ |
| 1676 | 1724 | \\pub extern fn foo(a: u8, b: u8, c: i8) c_int; |
| 1677 | | , |
| 1678 | 1725 | \\pub extern fn bar(a: u8, b: u16, c: u32, d: u64) void; |
| 1679 | | , |
| 1680 | 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 | 1730 | \\int abs(int a) { |
| 1685 | 1731 | \\ return a < 0 ? -a : a; |
| 1686 | 1732 | \\} |
| 1687 | 1733 | , &[_][]const u8{ |
| 1688 | | \\export fn abs(a: c_int) c_int { |
| 1689 | | \\ return if (a < 0) -a else a; |
| 1734 | \\pub export fn abs(a: c_int) c_int { |
| 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 | 1791 | cases.add("macro defines string literal with hex", |
| 1694 | 1792 | \\#define FOO "aoeu\xab derp" |
| 1695 | 1793 | \\#define FOO2 "aoeu\x0007a derp" |
| ... | ... | @@ -1714,28 +1812,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1714 | 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 | 1815 | cases.addC("shift right assign", |
| 1740 | 1816 | \\int log2(unsigned a) { |
| 1741 | 1817 | \\ int i = 0; |
| ... | ... | @@ -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 | 2072 | cases.addC("implicit casts", |
| 2087 | 2073 | \\#include <stdbool.h> |
| 2088 | 2074 | \\ |
| ... | ... | @@ -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 | 2626 | cases.add("variable name shadowing", |
| 2684 | 2627 | \\int foo(void) { |
| 2685 | 2628 | \\ int x = 1; |
| ... | ... | @@ -2726,4 +2669,80 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 2726 | 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 | } |