1cb93a386Sopenharmony_ci#include <metal_stdlib>
2cb93a386Sopenharmony_ci#include <simd/simd.h>
3cb93a386Sopenharmony_ciusing namespace metal;
4cb93a386Sopenharmony_cistruct S {
5cb93a386Sopenharmony_ci    float x;
6cb93a386Sopenharmony_ci    int y;
7cb93a386Sopenharmony_ci};
8cb93a386Sopenharmony_cistruct Nested {
9cb93a386Sopenharmony_ci    S a;
10cb93a386Sopenharmony_ci    S b;
11cb93a386Sopenharmony_ci};
12cb93a386Sopenharmony_cistruct Compound {
13cb93a386Sopenharmony_ci    float4 f4;
14cb93a386Sopenharmony_ci    int3 i3;
15cb93a386Sopenharmony_ci};
16cb93a386Sopenharmony_cistruct Uniforms {
17cb93a386Sopenharmony_ci    half4 colorRed;
18cb93a386Sopenharmony_ci    half4 colorGreen;
19cb93a386Sopenharmony_ci};
20cb93a386Sopenharmony_cistruct Inputs {
21cb93a386Sopenharmony_ci};
22cb93a386Sopenharmony_cistruct Outputs {
23cb93a386Sopenharmony_ci    half4 sk_FragColor [[color(0)]];
24cb93a386Sopenharmony_ci};
25cb93a386Sopenharmony_ci
26cb93a386Sopenharmony_cithread bool operator==(thread const S& left, thread const S& right);
27cb93a386Sopenharmony_cithread bool operator!=(thread const S& left, thread const S& right);
28cb93a386Sopenharmony_ci
29cb93a386Sopenharmony_cithread bool operator==(thread const Nested& left, thread const Nested& right);
30cb93a386Sopenharmony_cithread bool operator!=(thread const Nested& left, thread const Nested& right);
31cb93a386Sopenharmony_ci
32cb93a386Sopenharmony_cithread bool operator==(thread const Compound& left, thread const Compound& right);
33cb93a386Sopenharmony_cithread bool operator!=(thread const Compound& left, thread const Compound& right);
34cb93a386Sopenharmony_civoid modifies_a_struct_vS(thread S& s);
35cb93a386Sopenharmony_civoid _skOutParamHelper0_modifies_a_struct_vS(thread S& s) {
36cb93a386Sopenharmony_ci    S _var0 = s;
37cb93a386Sopenharmony_ci    modifies_a_struct_vS(_var0);
38cb93a386Sopenharmony_ci    s = _var0;
39cb93a386Sopenharmony_ci}
40cb93a386Sopenharmony_civoid modifies_a_struct_vS(thread S& s);
41cb93a386Sopenharmony_civoid _skOutParamHelper1_modifies_a_struct_vS(thread Nested& n3) {
42cb93a386Sopenharmony_ci    S _var0 = n3.b;
43cb93a386Sopenharmony_ci    modifies_a_struct_vS(_var0);
44cb93a386Sopenharmony_ci    n3.b = _var0;
45cb93a386Sopenharmony_ci}
46cb93a386Sopenharmony_cithread bool operator==(thread const S& left, thread const S& right) {
47cb93a386Sopenharmony_ci    return all(left.x == right.x) &&
48cb93a386Sopenharmony_ci           all(left.y == right.y);
49cb93a386Sopenharmony_ci}
50cb93a386Sopenharmony_cithread bool operator!=(thread const S& left, thread const S& right) {
51cb93a386Sopenharmony_ci    return !(left == right);
52cb93a386Sopenharmony_ci}
53cb93a386Sopenharmony_cithread bool operator==(thread const Nested& left, thread const Nested& right) {
54cb93a386Sopenharmony_ci    return all(left.a == right.a) &&
55cb93a386Sopenharmony_ci           all(left.b == right.b);
56cb93a386Sopenharmony_ci}
57cb93a386Sopenharmony_cithread bool operator!=(thread const Nested& left, thread const Nested& right) {
58cb93a386Sopenharmony_ci    return !(left == right);
59cb93a386Sopenharmony_ci}
60cb93a386Sopenharmony_cithread bool operator==(thread const Compound& left, thread const Compound& right) {
61cb93a386Sopenharmony_ci    return all(left.f4 == right.f4) &&
62cb93a386Sopenharmony_ci           all(left.i3 == right.i3);
63cb93a386Sopenharmony_ci}
64cb93a386Sopenharmony_cithread bool operator!=(thread const Compound& left, thread const Compound& right) {
65cb93a386Sopenharmony_ci    return !(left == right);
66cb93a386Sopenharmony_ci}
67cb93a386Sopenharmony_ciS returns_a_struct_S() {
68cb93a386Sopenharmony_ci    S s;
69cb93a386Sopenharmony_ci    s.x = 1.0;
70cb93a386Sopenharmony_ci    s.y = 2;
71cb93a386Sopenharmony_ci    return s;
72cb93a386Sopenharmony_ci}
73cb93a386Sopenharmony_ciS constructs_a_struct_S() {
74cb93a386Sopenharmony_ci    return S{2.0, 3};
75cb93a386Sopenharmony_ci}
76cb93a386Sopenharmony_cifloat accepts_a_struct_fS(S s) {
77cb93a386Sopenharmony_ci    return s.x + float(s.y);
78cb93a386Sopenharmony_ci}
79cb93a386Sopenharmony_civoid modifies_a_struct_vS(thread S& s) {
80cb93a386Sopenharmony_ci    s.x++;
81cb93a386Sopenharmony_ci    s.y++;
82cb93a386Sopenharmony_ci}
83cb93a386Sopenharmony_cifragment Outputs fragmentMain(Inputs _in [[stage_in]], constant Uniforms& _uniforms [[buffer(0)]], bool _frontFacing [[front_facing]], float4 _fragCoord [[position]]) {
84cb93a386Sopenharmony_ci    Outputs _out;
85cb93a386Sopenharmony_ci    (void)_out;
86cb93a386Sopenharmony_ci    S s = returns_a_struct_S();
87cb93a386Sopenharmony_ci    float x = accepts_a_struct_fS(s);
88cb93a386Sopenharmony_ci    _skOutParamHelper0_modifies_a_struct_vS(s);
89cb93a386Sopenharmony_ci    S expected = constructs_a_struct_S();
90cb93a386Sopenharmony_ci    Nested n1;
91cb93a386Sopenharmony_ci    Nested n2;
92cb93a386Sopenharmony_ci    Nested n3;
93cb93a386Sopenharmony_ci    n1.a = returns_a_struct_S();
94cb93a386Sopenharmony_ci    n1.b = n1.a;
95cb93a386Sopenharmony_ci    n2 = n1;
96cb93a386Sopenharmony_ci    n3 = n2;
97cb93a386Sopenharmony_ci    _skOutParamHelper1_modifies_a_struct_vS(n3);
98cb93a386Sopenharmony_ci    Compound c1 = Compound{float4(1.0, 2.0, 3.0, 4.0), int3(5, 6, 7)};
99cb93a386Sopenharmony_ci    Compound c2 = Compound{float4(float(_uniforms.colorGreen.y), 2.0, 3.0, 4.0), int3(5, 6, 7)};
100cb93a386Sopenharmony_ci    Compound c3 = Compound{float4(float(_uniforms.colorGreen.x), 2.0, 3.0, 4.0), int3(5, 6, 7)};
101cb93a386Sopenharmony_ci    bool valid = (((((((((x == 3.0 && s.x == 2.0) && s.y == 3) && s == expected) && s == S{2.0, 3}) && s != returns_a_struct_S()) && n1 == n2) && n1 != n3) && n3 == Nested{S{1.0, 2}, S{2.0, 3}}) && c1 == c2) && c2 != c3;
102cb93a386Sopenharmony_ci    _out.sk_FragColor = valid ? _uniforms.colorGreen : _uniforms.colorRed;
103cb93a386Sopenharmony_ci    return _out;
104cb93a386Sopenharmony_ci}
105