1 // Copyright 2021 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/transform/wrap_arrays_in_structs.h"
16
17 #include <memory>
18 #include <utility>
19
20 #include "src/transform/test_helper.h"
21
22 namespace tint {
23 namespace transform {
24 namespace {
25
26 using WrapArraysInStructsTest = TransformTest;
27
TEST_F(WrapArraysInStructsTest,EmptyModule)28 TEST_F(WrapArraysInStructsTest, EmptyModule) {
29 auto* src = "";
30 auto* expect = "";
31
32 auto got = Run<WrapArraysInStructs>(src);
33
34 EXPECT_EQ(expect, str(got));
35 }
36
TEST_F(WrapArraysInStructsTest,ArrayAsGlobal)37 TEST_F(WrapArraysInStructsTest, ArrayAsGlobal) {
38 auto* src = R"(
39 var<private> arr : array<i32, 4>;
40 )";
41 auto* expect = R"(
42 struct tint_array_wrapper {
43 arr : array<i32, 4u>;
44 };
45
46 var<private> arr : tint_array_wrapper;
47 )";
48
49 auto got = Run<WrapArraysInStructs>(src);
50
51 EXPECT_EQ(expect, str(got));
52 }
53
TEST_F(WrapArraysInStructsTest,ArrayAsFunctionVar)54 TEST_F(WrapArraysInStructsTest, ArrayAsFunctionVar) {
55 auto* src = R"(
56 fn f() {
57 var arr : array<i32, 4>;
58 let x = arr[3];
59 }
60 )";
61 auto* expect = R"(
62 struct tint_array_wrapper {
63 arr : array<i32, 4u>;
64 };
65
66 fn f() {
67 var arr : tint_array_wrapper;
68 let x = arr.arr[3];
69 }
70 )";
71
72 auto got = Run<WrapArraysInStructs>(src);
73
74 EXPECT_EQ(expect, str(got));
75 }
76
TEST_F(WrapArraysInStructsTest,ArrayAsParam)77 TEST_F(WrapArraysInStructsTest, ArrayAsParam) {
78 auto* src = R"(
79 fn f(a : array<i32, 4>) -> i32 {
80 return a[2];
81 }
82 )";
83 auto* expect = R"(
84 struct tint_array_wrapper {
85 arr : array<i32, 4u>;
86 };
87
88 fn f(a : tint_array_wrapper) -> i32 {
89 return a.arr[2];
90 }
91 )";
92
93 auto got = Run<WrapArraysInStructs>(src);
94
95 EXPECT_EQ(expect, str(got));
96 }
97
TEST_F(WrapArraysInStructsTest,ArrayAsReturn)98 TEST_F(WrapArraysInStructsTest, ArrayAsReturn) {
99 auto* src = R"(
100 fn f() -> array<i32, 4> {
101 return array<i32, 4>(1, 2, 3, 4);
102 }
103 )";
104 auto* expect = R"(
105 struct tint_array_wrapper {
106 arr : array<i32, 4u>;
107 };
108
109 fn f() -> tint_array_wrapper {
110 return tint_array_wrapper(array<i32, 4u>(1, 2, 3, 4));
111 }
112 )";
113
114 auto got = Run<WrapArraysInStructs>(src);
115
116 EXPECT_EQ(expect, str(got));
117 }
118
TEST_F(WrapArraysInStructsTest,ArrayAlias)119 TEST_F(WrapArraysInStructsTest, ArrayAlias) {
120 auto* src = R"(
121 type Inner = array<i32, 2>;
122 type Array = array<Inner, 2>;
123
124 fn f() {
125 var arr : Array;
126 arr = Array();
127 arr = Array(Inner(1, 2), Inner(3, 4));
128 let vals : Array = Array(Inner(1, 2), Inner(3, 4));
129 arr = vals;
130 let x = arr[3];
131 }
132 )";
133 auto* expect = R"(
134 struct tint_array_wrapper {
135 arr : array<i32, 2u>;
136 };
137
138 type Inner = tint_array_wrapper;
139
140 struct tint_array_wrapper_1 {
141 arr : array<tint_array_wrapper, 2u>;
142 };
143
144 type Array = tint_array_wrapper_1;
145
146 fn f() {
147 var arr : tint_array_wrapper_1;
148 arr = tint_array_wrapper_1(array<tint_array_wrapper, 2u>());
149 arr = tint_array_wrapper_1(array<tint_array_wrapper, 2u>(tint_array_wrapper(array<i32, 2u>(1, 2)), tint_array_wrapper(array<i32, 2u>(3, 4))));
150 let vals : tint_array_wrapper_1 = tint_array_wrapper_1(array<tint_array_wrapper, 2u>(tint_array_wrapper(array<i32, 2u>(1, 2)), tint_array_wrapper(array<i32, 2u>(3, 4))));
151 arr = vals;
152 let x = arr.arr[3];
153 }
154 )";
155
156 auto got = Run<WrapArraysInStructs>(src);
157
158 EXPECT_EQ(expect, str(got));
159 }
160
TEST_F(WrapArraysInStructsTest,ArraysInStruct)161 TEST_F(WrapArraysInStructsTest, ArraysInStruct) {
162 auto* src = R"(
163 struct S {
164 a : array<i32, 4>;
165 b : array<i32, 8>;
166 c : array<i32, 4>;
167 };
168 )";
169 auto* expect = R"(
170 struct tint_array_wrapper {
171 arr : array<i32, 4u>;
172 };
173
174 struct tint_array_wrapper_1 {
175 arr : array<i32, 8u>;
176 };
177
178 struct S {
179 a : tint_array_wrapper;
180 b : tint_array_wrapper_1;
181 c : tint_array_wrapper;
182 };
183 )";
184
185 auto got = Run<WrapArraysInStructs>(src);
186
187 EXPECT_EQ(expect, str(got));
188 }
189
TEST_F(WrapArraysInStructsTest,ArraysOfArraysInStruct)190 TEST_F(WrapArraysInStructsTest, ArraysOfArraysInStruct) {
191 auto* src = R"(
192 struct S {
193 a : array<i32, 4>;
194 b : array<array<i32, 4>, 4>;
195 c : array<array<array<i32, 4>, 4>, 4>;
196 };
197 )";
198 auto* expect = R"(
199 struct tint_array_wrapper {
200 arr : array<i32, 4u>;
201 };
202
203 struct tint_array_wrapper_1 {
204 arr : array<tint_array_wrapper, 4u>;
205 };
206
207 struct tint_array_wrapper_2 {
208 arr : array<tint_array_wrapper_1, 4u>;
209 };
210
211 struct S {
212 a : tint_array_wrapper;
213 b : tint_array_wrapper_1;
214 c : tint_array_wrapper_2;
215 };
216 )";
217
218 auto got = Run<WrapArraysInStructs>(src);
219
220 EXPECT_EQ(expect, str(got));
221 }
222
TEST_F(WrapArraysInStructsTest,AccessArraysOfArraysInStruct)223 TEST_F(WrapArraysInStructsTest, AccessArraysOfArraysInStruct) {
224 auto* src = R"(
225 struct S {
226 a : array<i32, 4>;
227 b : array<array<i32, 4>, 4>;
228 c : array<array<array<i32, 4>, 4>, 4>;
229 };
230
231 fn f(s : S) -> i32 {
232 return s.a[2] + s.b[1][2] + s.c[3][1][2];
233 }
234 )";
235 auto* expect = R"(
236 struct tint_array_wrapper {
237 arr : array<i32, 4u>;
238 };
239
240 struct tint_array_wrapper_1 {
241 arr : array<tint_array_wrapper, 4u>;
242 };
243
244 struct tint_array_wrapper_2 {
245 arr : array<tint_array_wrapper_1, 4u>;
246 };
247
248 struct S {
249 a : tint_array_wrapper;
250 b : tint_array_wrapper_1;
251 c : tint_array_wrapper_2;
252 };
253
254 fn f(s : S) -> i32 {
255 return ((s.a.arr[2] + s.b.arr[1].arr[2]) + s.c.arr[3].arr[1].arr[2]);
256 }
257 )";
258
259 auto got = Run<WrapArraysInStructs>(src);
260
261 EXPECT_EQ(expect, str(got));
262 }
263
TEST_F(WrapArraysInStructsTest,DeclarationOrder)264 TEST_F(WrapArraysInStructsTest, DeclarationOrder) {
265 auto* src = R"(
266 type T0 = i32;
267
268 type T1 = array<i32, 1>;
269
270 type T2 = i32;
271
272 fn f1(a : array<i32, 2>) {
273 }
274
275 type T3 = i32;
276
277 fn f2() {
278 var v : array<i32, 3>;
279 }
280 )";
281 auto* expect = R"(
282 type T0 = i32;
283
284 struct tint_array_wrapper {
285 arr : array<i32, 1u>;
286 };
287
288 type T1 = tint_array_wrapper;
289
290 type T2 = i32;
291
292 struct tint_array_wrapper_1 {
293 arr : array<i32, 2u>;
294 };
295
296 fn f1(a : tint_array_wrapper_1) {
297 }
298
299 type T3 = i32;
300
301 struct tint_array_wrapper_2 {
302 arr : array<i32, 3u>;
303 };
304
305 fn f2() {
306 var v : tint_array_wrapper_2;
307 }
308 )";
309
310 auto got = Run<WrapArraysInStructs>(src);
311
312 EXPECT_EQ(expect, str(got));
313 }
314
315 } // namespace
316 } // namespace transform
317 } // namespace tint
318