1 // Copyright 2020 The Tint Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "src/writer/wgsl/test_helper.h"
16
17 namespace tint {
18 namespace writer {
19 namespace wgsl {
20 namespace {
21
22 using WgslGeneratorImplTest = TestHelper;
23
TEST_F(WgslGeneratorImplTest,Emit_Loop)24 TEST_F(WgslGeneratorImplTest, Emit_Loop) {
25 auto* body = Block(create<ast::DiscardStatement>());
26 auto* continuing = Block();
27 auto* l = Loop(body, continuing);
28
29 WrapInFunction(l);
30
31 GeneratorImpl& gen = Build();
32
33 gen.increment_indent();
34
35 ASSERT_TRUE(gen.EmitStatement(l)) << gen.error();
36 EXPECT_EQ(gen.result(), R"( loop {
37 discard;
38 }
39 )");
40 }
41
TEST_F(WgslGeneratorImplTest,Emit_LoopWithContinuing)42 TEST_F(WgslGeneratorImplTest, Emit_LoopWithContinuing) {
43 Func("a_statement", {}, ty.void_(), {});
44
45 auto* body = Block(create<ast::DiscardStatement>());
46 auto* continuing = Block(CallStmt(Call("a_statement")));
47 auto* l = Loop(body, continuing);
48
49 WrapInFunction(l);
50
51 GeneratorImpl& gen = Build();
52
53 gen.increment_indent();
54
55 ASSERT_TRUE(gen.EmitStatement(l)) << gen.error();
56 EXPECT_EQ(gen.result(), R"( loop {
57 discard;
58
59 continuing {
60 a_statement();
61 }
62 }
63 )");
64 }
65
TEST_F(WgslGeneratorImplTest,Emit_ForLoopWithMultiStmtInit)66 TEST_F(WgslGeneratorImplTest, Emit_ForLoopWithMultiStmtInit) {
67 // var<workgroup> a : atomic<i32>;
68 // for({ignore(1); ignore(2);}; ; ) {
69 // return;
70 // }
71 Global("a", ty.atomic<i32>(), ast::StorageClass::kWorkgroup);
72 auto* multi_stmt = Block(Ignore(1), Ignore(2));
73 auto* f = For(multi_stmt, nullptr, nullptr, Block(Return()));
74 WrapInFunction(f);
75
76 GeneratorImpl& gen = Build();
77
78 gen.increment_indent();
79
80 ASSERT_TRUE(gen.EmitStatement(f)) << gen.error();
81 EXPECT_EQ(gen.result(), R"( for({
82 _ = 1;
83 _ = 2;
84 }; ; ) {
85 return;
86 }
87 )");
88 }
89
TEST_F(WgslGeneratorImplTest,Emit_ForLoopWithSimpleCond)90 TEST_F(WgslGeneratorImplTest, Emit_ForLoopWithSimpleCond) {
91 // for(; true; ) {
92 // return;
93 // }
94
95 auto* f = For(nullptr, true, nullptr, Block(Return()));
96 WrapInFunction(f);
97
98 GeneratorImpl& gen = Build();
99
100 gen.increment_indent();
101
102 ASSERT_TRUE(gen.EmitStatement(f)) << gen.error();
103 EXPECT_EQ(gen.result(), R"( for(; true; ) {
104 return;
105 }
106 )");
107 }
108
TEST_F(WgslGeneratorImplTest,Emit_ForLoopWithSimpleCont)109 TEST_F(WgslGeneratorImplTest, Emit_ForLoopWithSimpleCont) {
110 // for(; ; i = i + 1) {
111 // return;
112 // }
113
114 auto* v = Decl(Var("i", ty.i32()));
115 auto* f = For(nullptr, nullptr, Assign("i", Add("i", 1)), Block(Return()));
116 WrapInFunction(v, f);
117
118 GeneratorImpl& gen = Build();
119
120 gen.increment_indent();
121
122 ASSERT_TRUE(gen.EmitStatement(f)) << gen.error();
123 EXPECT_EQ(gen.result(), R"( for(; ; i = (i + 1)) {
124 return;
125 }
126 )");
127 }
128
TEST_F(WgslGeneratorImplTest,Emit_ForLoopWithMultiStmtCont)129 TEST_F(WgslGeneratorImplTest, Emit_ForLoopWithMultiStmtCont) {
130 // var<workgroup> a : atomic<i32>;
131 // for(; ; { ignore(1); ignore(2); }) {
132 // return;
133 // }
134
135 Global("a", ty.atomic<i32>(), ast::StorageClass::kWorkgroup);
136 auto* multi_stmt = Block(Ignore(1), Ignore(2));
137 auto* f = For(nullptr, nullptr, multi_stmt, Block(Return()));
138 WrapInFunction(f);
139
140 GeneratorImpl& gen = Build();
141
142 gen.increment_indent();
143
144 ASSERT_TRUE(gen.EmitStatement(f)) << gen.error();
145 EXPECT_EQ(gen.result(), R"( for(; ; {
146 _ = 1;
147 _ = 2;
148 }) {
149 return;
150 }
151 )");
152 }
153
TEST_F(WgslGeneratorImplTest,Emit_ForLoopWithSimpleInitCondCont)154 TEST_F(WgslGeneratorImplTest, Emit_ForLoopWithSimpleInitCondCont) {
155 // for(var i : i32; true; i = i + 1) {
156 // return;
157 // }
158
159 auto* f = For(Decl(Var("i", ty.i32())), true, Assign("i", Add("i", 1)),
160 Block(Return()));
161 WrapInFunction(f);
162
163 GeneratorImpl& gen = Build();
164
165 gen.increment_indent();
166
167 ASSERT_TRUE(gen.EmitStatement(f)) << gen.error();
168 EXPECT_EQ(gen.result(), R"( for(var i : i32; true; i = (i + 1)) {
169 return;
170 }
171 )");
172 }
173
TEST_F(WgslGeneratorImplTest,Emit_ForLoopWithMultiStmtInitCondCont)174 TEST_F(WgslGeneratorImplTest, Emit_ForLoopWithMultiStmtInitCondCont) {
175 // var<workgroup> a : atomic<i32>;
176 // for({ ignore(1); ignore(2); }; true; { ignore(3); ignore(4); }) {
177 // return;
178 // }
179 Global("a", ty.atomic<i32>(), ast::StorageClass::kWorkgroup);
180 auto* multi_stmt_a = Block(Ignore(1), Ignore(2));
181 auto* multi_stmt_b = Block(Ignore(3), Ignore(4));
182 auto* f = For(multi_stmt_a, Expr(true), multi_stmt_b, Block(Return()));
183 WrapInFunction(f);
184
185 GeneratorImpl& gen = Build();
186
187 gen.increment_indent();
188
189 ASSERT_TRUE(gen.EmitStatement(f)) << gen.error();
190 EXPECT_EQ(gen.result(), R"( for({
191 _ = 1;
192 _ = 2;
193 }; true; {
194 _ = 3;
195 _ = 4;
196 }) {
197 return;
198 }
199 )");
200 }
201
202 } // namespace
203 } // namespace wgsl
204 } // namespace writer
205 } // namespace tint
206