// Copyright 2021 The Tint Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include "src/transform/wrap_arrays_in_structs.h" #include #include #include "src/transform/test_helper.h" namespace tint { namespace transform { namespace { using WrapArraysInStructsTest = TransformTest; TEST_F(WrapArraysInStructsTest, EmptyModule) { auto* src = ""; auto* expect = ""; auto got = Run(src); EXPECT_EQ(expect, str(got)); } TEST_F(WrapArraysInStructsTest, ArrayAsGlobal) { auto* src = R"( var arr : array; )"; auto* expect = R"( struct tint_array_wrapper { arr : array; }; var arr : tint_array_wrapper; )"; auto got = Run(src); EXPECT_EQ(expect, str(got)); } TEST_F(WrapArraysInStructsTest, ArrayAsFunctionVar) { auto* src = R"( fn f() { var arr : array; let x = arr[3]; } )"; auto* expect = R"( struct tint_array_wrapper { arr : array; }; fn f() { var arr : tint_array_wrapper; let x = arr.arr[3]; } )"; auto got = Run(src); EXPECT_EQ(expect, str(got)); } TEST_F(WrapArraysInStructsTest, ArrayAsParam) { auto* src = R"( fn f(a : array) -> i32 { return a[2]; } )"; auto* expect = R"( struct tint_array_wrapper { arr : array; }; fn f(a : tint_array_wrapper) -> i32 { return a.arr[2]; } )"; auto got = Run(src); EXPECT_EQ(expect, str(got)); } TEST_F(WrapArraysInStructsTest, ArrayAsReturn) { auto* src = R"( fn f() -> array { return array(1, 2, 3, 4); } )"; auto* expect = R"( struct tint_array_wrapper { arr : array; }; fn f() -> tint_array_wrapper { return tint_array_wrapper(array(1, 2, 3, 4)); } )"; auto got = Run(src); EXPECT_EQ(expect, str(got)); } TEST_F(WrapArraysInStructsTest, ArrayAlias) { auto* src = R"( type Inner = array; type Array = array; fn f() { var arr : Array; arr = Array(); arr = Array(Inner(1, 2), Inner(3, 4)); let vals : Array = Array(Inner(1, 2), Inner(3, 4)); arr = vals; let x = arr[3]; } )"; auto* expect = R"( struct tint_array_wrapper { arr : array; }; type Inner = tint_array_wrapper; struct tint_array_wrapper_1 { arr : array; }; type Array = tint_array_wrapper_1; fn f() { var arr : tint_array_wrapper_1; arr = tint_array_wrapper_1(array()); arr = tint_array_wrapper_1(array(tint_array_wrapper(array(1, 2)), tint_array_wrapper(array(3, 4)))); let vals : tint_array_wrapper_1 = tint_array_wrapper_1(array(tint_array_wrapper(array(1, 2)), tint_array_wrapper(array(3, 4)))); arr = vals; let x = arr.arr[3]; } )"; auto got = Run(src); EXPECT_EQ(expect, str(got)); } TEST_F(WrapArraysInStructsTest, ArraysInStruct) { auto* src = R"( struct S { a : array; b : array; c : array; }; )"; auto* expect = R"( struct tint_array_wrapper { arr : array; }; struct tint_array_wrapper_1 { arr : array; }; struct S { a : tint_array_wrapper; b : tint_array_wrapper_1; c : tint_array_wrapper; }; )"; auto got = Run(src); EXPECT_EQ(expect, str(got)); } TEST_F(WrapArraysInStructsTest, ArraysOfArraysInStruct) { auto* src = R"( struct S { a : array; b : array, 4>; c : array, 4>, 4>; }; )"; auto* expect = R"( struct tint_array_wrapper { arr : array; }; struct tint_array_wrapper_1 { arr : array; }; struct tint_array_wrapper_2 { arr : array; }; struct S { a : tint_array_wrapper; b : tint_array_wrapper_1; c : tint_array_wrapper_2; }; )"; auto got = Run(src); EXPECT_EQ(expect, str(got)); } TEST_F(WrapArraysInStructsTest, AccessArraysOfArraysInStruct) { auto* src = R"( struct S { a : array; b : array, 4>; c : array, 4>, 4>; }; fn f(s : S) -> i32 { return s.a[2] + s.b[1][2] + s.c[3][1][2]; } )"; auto* expect = R"( struct tint_array_wrapper { arr : array; }; struct tint_array_wrapper_1 { arr : array; }; struct tint_array_wrapper_2 { arr : array; }; struct S { a : tint_array_wrapper; b : tint_array_wrapper_1; c : tint_array_wrapper_2; }; fn f(s : S) -> i32 { return ((s.a.arr[2] + s.b.arr[1].arr[2]) + s.c.arr[3].arr[1].arr[2]); } )"; auto got = Run(src); EXPECT_EQ(expect, str(got)); } TEST_F(WrapArraysInStructsTest, DeclarationOrder) { auto* src = R"( type T0 = i32; type T1 = array; type T2 = i32; fn f1(a : array) { } type T3 = i32; fn f2() { var v : array; } )"; auto* expect = R"( type T0 = i32; struct tint_array_wrapper { arr : array; }; type T1 = tint_array_wrapper; type T2 = i32; struct tint_array_wrapper_1 { arr : array; }; fn f1(a : tint_array_wrapper_1) { } type T3 = i32; struct tint_array_wrapper_2 { arr : array; }; fn f2() { var v : tint_array_wrapper_2; } )"; auto got = Run(src); EXPECT_EQ(expect, str(got)); } } // namespace } // namespace transform } // namespace tint