blob: c0b417c81b4d7dfa4e91119e7423dd875e36a0f3 [file] [log] [blame]
Ryan Harrisondbc13af2022-02-21 15:19:07 +00001// 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/tint/resolver/resolver.h"
16
17#include "gmock/gmock.h"
18#include "src/tint/resolver/resolver_test_helper.h"
Antonio Maioranodfeaf2902022-06-24 20:34:00 +000019#include "src/tint/sem/index_accessor_expression.h"
Ben Clayton01004b72022-04-28 18:49:04 +000020#include "src/tint/sem/reference.h"
Ryan Harrisondbc13af2022-02-21 15:19:07 +000021
Ben Clayton0ce9ab02022-05-05 20:23:40 +000022using namespace tint::number_suffixes; // NOLINT
23
dan sinclaird2093792022-04-07 17:45:45 +000024namespace tint::resolver {
Ryan Harrisondbc13af2022-02-21 15:19:07 +000025namespace {
26
27using ResolverIndexAccessorTest = ResolverTest;
28
29TEST_F(ResolverIndexAccessorTest, Matrix_Dynamic_F32) {
Ben Clayton01208e72022-06-25 08:12:59 +000030 GlobalVar("my_var", ty.mat2x3<f32>(), ast::StorageClass::kPrivate);
Ben Clayton0a3cda92022-05-10 17:30:15 +000031 auto* acc = IndexAccessor("my_var", Expr(Source{{12, 34}}, 1_f));
dan sinclair41e4d9a2022-05-01 14:40:55 +000032 WrapInFunction(acc);
Ryan Harrisondbc13af2022-02-21 15:19:07 +000033
dan sinclair41e4d9a2022-05-01 14:40:55 +000034 EXPECT_FALSE(r()->Resolve());
35 EXPECT_EQ(r()->error(), "12:34 error: index must be of type 'i32' or 'u32', found: 'f32'");
Ryan Harrisondbc13af2022-02-21 15:19:07 +000036}
37
38TEST_F(ResolverIndexAccessorTest, Matrix_Dynamic_Ref) {
Ben Clayton01208e72022-06-25 08:12:59 +000039 GlobalVar("my_var", ty.mat2x3<f32>(), ast::StorageClass::kPrivate);
dan sinclair41e4d9a2022-05-01 14:40:55 +000040 auto* idx = Var("idx", ty.i32(), Construct(ty.i32()));
41 auto* acc = IndexAccessor("my_var", idx);
42 WrapInFunction(Decl(idx), acc);
Ryan Harrisondbc13af2022-02-21 15:19:07 +000043
dan sinclair41e4d9a2022-05-01 14:40:55 +000044 EXPECT_TRUE(r()->Resolve()) << r()->error();
Antonio Maioranodfeaf2902022-06-24 20:34:00 +000045
46 auto idx_sem = Sem().Get(acc);
47 ASSERT_NE(idx_sem, nullptr);
48 EXPECT_EQ(idx_sem->Index()->Declaration(), acc->index);
49 EXPECT_EQ(idx_sem->Object()->Declaration(), acc->object);
Ryan Harrisondbc13af2022-02-21 15:19:07 +000050}
51
52TEST_F(ResolverIndexAccessorTest, Matrix_BothDimensions_Dynamic_Ref) {
Ben Clayton01208e72022-06-25 08:12:59 +000053 GlobalVar("my_var", ty.mat4x4<f32>(), ast::StorageClass::kPrivate);
Ben Clayton0ce9ab02022-05-05 20:23:40 +000054 auto* idx = Var("idx", ty.u32(), Expr(3_u));
55 auto* idy = Var("idy", ty.u32(), Expr(2_u));
dan sinclair41e4d9a2022-05-01 14:40:55 +000056 auto* acc = IndexAccessor(IndexAccessor("my_var", idx), idy);
57 WrapInFunction(Decl(idx), Decl(idy), acc);
Ryan Harrisondbc13af2022-02-21 15:19:07 +000058
dan sinclair41e4d9a2022-05-01 14:40:55 +000059 EXPECT_TRUE(r()->Resolve()) << r()->error();
Antonio Maioranodfeaf2902022-06-24 20:34:00 +000060
61 auto idx_sem = Sem().Get(acc);
62 ASSERT_NE(idx_sem, nullptr);
63 EXPECT_EQ(idx_sem->Index()->Declaration(), acc->index);
64 EXPECT_EQ(idx_sem->Object()->Declaration(), acc->object);
Ryan Harrisondbc13af2022-02-21 15:19:07 +000065}
66
67TEST_F(ResolverIndexAccessorTest, Matrix_Dynamic) {
Ben Clayton41486e12022-06-25 07:17:29 +000068 GlobalLet("my_const", ty.mat2x3<f32>(), Construct(ty.mat2x3<f32>()));
dan sinclair41e4d9a2022-05-01 14:40:55 +000069 auto* idx = Var("idx", ty.i32(), Construct(ty.i32()));
70 auto* acc = IndexAccessor("my_const", Expr(Source{{12, 34}}, idx));
71 WrapInFunction(Decl(idx), acc);
Ryan Harrisondbc13af2022-02-21 15:19:07 +000072
dan sinclair41e4d9a2022-05-01 14:40:55 +000073 EXPECT_TRUE(r()->Resolve());
74 EXPECT_EQ(r()->error(), "");
Antonio Maioranodfeaf2902022-06-24 20:34:00 +000075
76 auto idx_sem = Sem().Get(acc);
77 ASSERT_NE(idx_sem, nullptr);
78 EXPECT_EQ(idx_sem->Index()->Declaration(), acc->index);
79 EXPECT_EQ(idx_sem->Object()->Declaration(), acc->object);
Ryan Harrisondbc13af2022-02-21 15:19:07 +000080}
81
82TEST_F(ResolverIndexAccessorTest, Matrix_XDimension_Dynamic) {
Ben Clayton41486e12022-06-25 07:17:29 +000083 GlobalLet("my_var", ty.mat4x4<f32>(), Construct(ty.mat4x4<f32>()));
Ben Clayton0ce9ab02022-05-05 20:23:40 +000084 auto* idx = Var("idx", ty.u32(), Expr(3_u));
dan sinclair41e4d9a2022-05-01 14:40:55 +000085 auto* acc = IndexAccessor("my_var", Expr(Source{{12, 34}}, idx));
86 WrapInFunction(Decl(idx), acc);
Ryan Harrisondbc13af2022-02-21 15:19:07 +000087
dan sinclair41e4d9a2022-05-01 14:40:55 +000088 EXPECT_TRUE(r()->Resolve());
89 EXPECT_EQ(r()->error(), "");
Antonio Maioranodfeaf2902022-06-24 20:34:00 +000090
91 auto idx_sem = Sem().Get(acc);
92 ASSERT_NE(idx_sem, nullptr);
93 EXPECT_EQ(idx_sem->Index()->Declaration(), acc->index);
94 EXPECT_EQ(idx_sem->Object()->Declaration(), acc->object);
Ryan Harrisondbc13af2022-02-21 15:19:07 +000095}
96
97TEST_F(ResolverIndexAccessorTest, Matrix_BothDimension_Dynamic) {
Ben Clayton41486e12022-06-25 07:17:29 +000098 GlobalLet("my_var", ty.mat4x4<f32>(), Construct(ty.mat4x4<f32>()));
Ben Clayton0ce9ab02022-05-05 20:23:40 +000099 auto* idx = Var("idy", ty.u32(), Expr(2_u));
100 auto* acc = IndexAccessor(IndexAccessor("my_var", Expr(Source{{12, 34}}, idx)), 1_i);
dan sinclair41e4d9a2022-05-01 14:40:55 +0000101 WrapInFunction(Decl(idx), acc);
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000102
dan sinclair41e4d9a2022-05-01 14:40:55 +0000103 EXPECT_TRUE(r()->Resolve());
104 EXPECT_EQ(r()->error(), "");
Antonio Maioranodfeaf2902022-06-24 20:34:00 +0000105
106 auto idx_sem = Sem().Get(acc);
107 ASSERT_NE(idx_sem, nullptr);
108 EXPECT_EQ(idx_sem->Index()->Declaration(), acc->index);
109 EXPECT_EQ(idx_sem->Object()->Declaration(), acc->object);
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000110}
111
112TEST_F(ResolverIndexAccessorTest, Matrix) {
Ben Clayton01208e72022-06-25 08:12:59 +0000113 GlobalVar("my_var", ty.mat2x3<f32>(), ast::StorageClass::kPrivate);
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000114
Ben Clayton0ce9ab02022-05-05 20:23:40 +0000115 auto* acc = IndexAccessor("my_var", 2_i);
dan sinclair41e4d9a2022-05-01 14:40:55 +0000116 WrapInFunction(acc);
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000117
dan sinclair41e4d9a2022-05-01 14:40:55 +0000118 EXPECT_TRUE(r()->Resolve()) << r()->error();
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000119
dan sinclair41e4d9a2022-05-01 14:40:55 +0000120 ASSERT_NE(TypeOf(acc), nullptr);
121 ASSERT_TRUE(TypeOf(acc)->Is<sem::Reference>());
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000122
dan sinclair41e4d9a2022-05-01 14:40:55 +0000123 auto* ref = TypeOf(acc)->As<sem::Reference>();
124 ASSERT_TRUE(ref->StoreType()->Is<sem::Vector>());
125 EXPECT_EQ(ref->StoreType()->As<sem::Vector>()->Width(), 3u);
Antonio Maioranodfeaf2902022-06-24 20:34:00 +0000126
127 auto idx_sem = Sem().Get(acc);
128 ASSERT_NE(idx_sem, nullptr);
129 EXPECT_EQ(idx_sem->Index()->Declaration(), acc->index);
130 EXPECT_EQ(idx_sem->Object()->Declaration(), acc->object);
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000131}
132
133TEST_F(ResolverIndexAccessorTest, Matrix_BothDimensions) {
Ben Clayton01208e72022-06-25 08:12:59 +0000134 GlobalVar("my_var", ty.mat2x3<f32>(), ast::StorageClass::kPrivate);
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000135
Ben Clayton0ce9ab02022-05-05 20:23:40 +0000136 auto* acc = IndexAccessor(IndexAccessor("my_var", 2_i), 1_i);
dan sinclair41e4d9a2022-05-01 14:40:55 +0000137 WrapInFunction(acc);
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000138
dan sinclair41e4d9a2022-05-01 14:40:55 +0000139 EXPECT_TRUE(r()->Resolve()) << r()->error();
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000140
dan sinclair41e4d9a2022-05-01 14:40:55 +0000141 ASSERT_NE(TypeOf(acc), nullptr);
142 ASSERT_TRUE(TypeOf(acc)->Is<sem::Reference>());
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000143
dan sinclair41e4d9a2022-05-01 14:40:55 +0000144 auto* ref = TypeOf(acc)->As<sem::Reference>();
145 EXPECT_TRUE(ref->StoreType()->Is<sem::F32>());
Antonio Maioranodfeaf2902022-06-24 20:34:00 +0000146
147 auto idx_sem = Sem().Get(acc);
148 ASSERT_NE(idx_sem, nullptr);
149 EXPECT_EQ(idx_sem->Index()->Declaration(), acc->index);
150 EXPECT_EQ(idx_sem->Object()->Declaration(), acc->object);
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000151}
152
153TEST_F(ResolverIndexAccessorTest, Vector_F32) {
Ben Clayton01208e72022-06-25 08:12:59 +0000154 GlobalVar("my_var", ty.vec3<f32>(), ast::StorageClass::kPrivate);
Ben Clayton0a3cda92022-05-10 17:30:15 +0000155 auto* acc = IndexAccessor("my_var", Expr(Source{{12, 34}}, 2_f));
dan sinclair41e4d9a2022-05-01 14:40:55 +0000156 WrapInFunction(acc);
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000157
dan sinclair41e4d9a2022-05-01 14:40:55 +0000158 EXPECT_FALSE(r()->Resolve());
159 EXPECT_EQ(r()->error(), "12:34 error: index must be of type 'i32' or 'u32', found: 'f32'");
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000160}
161
162TEST_F(ResolverIndexAccessorTest, Vector_Dynamic_Ref) {
Ben Clayton01208e72022-06-25 08:12:59 +0000163 GlobalVar("my_var", ty.vec3<f32>(), ast::StorageClass::kPrivate);
Ben Clayton0ce9ab02022-05-05 20:23:40 +0000164 auto* idx = Var("idx", ty.i32(), Expr(2_i));
dan sinclair41e4d9a2022-05-01 14:40:55 +0000165 auto* acc = IndexAccessor("my_var", idx);
166 WrapInFunction(Decl(idx), acc);
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000167
dan sinclair41e4d9a2022-05-01 14:40:55 +0000168 EXPECT_TRUE(r()->Resolve());
Antonio Maioranodfeaf2902022-06-24 20:34:00 +0000169
170 auto idx_sem = Sem().Get(acc);
171 ASSERT_NE(idx_sem, nullptr);
172 EXPECT_EQ(idx_sem->Index()->Declaration(), acc->index);
173 EXPECT_EQ(idx_sem->Object()->Declaration(), acc->object);
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000174}
175
176TEST_F(ResolverIndexAccessorTest, Vector_Dynamic) {
Ben Clayton41486e12022-06-25 07:17:29 +0000177 GlobalLet("my_var", ty.vec3<f32>(), Construct(ty.vec3<f32>()));
Ben Clayton0ce9ab02022-05-05 20:23:40 +0000178 auto* idx = Var("idx", ty.i32(), Expr(2_i));
dan sinclair41e4d9a2022-05-01 14:40:55 +0000179 auto* acc = IndexAccessor("my_var", Expr(Source{{12, 34}}, idx));
180 WrapInFunction(Decl(idx), acc);
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000181
dan sinclair41e4d9a2022-05-01 14:40:55 +0000182 EXPECT_TRUE(r()->Resolve());
Antonio Maioranodfeaf2902022-06-24 20:34:00 +0000183
184 auto idx_sem = Sem().Get(acc);
185 ASSERT_NE(idx_sem, nullptr);
186 EXPECT_EQ(idx_sem->Index()->Declaration(), acc->index);
187 EXPECT_EQ(idx_sem->Object()->Declaration(), acc->object);
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000188}
189
190TEST_F(ResolverIndexAccessorTest, Vector) {
Ben Clayton01208e72022-06-25 08:12:59 +0000191 GlobalVar("my_var", ty.vec3<f32>(), ast::StorageClass::kPrivate);
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000192
Ben Clayton0ce9ab02022-05-05 20:23:40 +0000193 auto* acc = IndexAccessor("my_var", 2_i);
dan sinclair41e4d9a2022-05-01 14:40:55 +0000194 WrapInFunction(acc);
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000195
dan sinclair41e4d9a2022-05-01 14:40:55 +0000196 EXPECT_TRUE(r()->Resolve()) << r()->error();
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000197
dan sinclair41e4d9a2022-05-01 14:40:55 +0000198 ASSERT_NE(TypeOf(acc), nullptr);
199 ASSERT_TRUE(TypeOf(acc)->Is<sem::Reference>());
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000200
dan sinclair41e4d9a2022-05-01 14:40:55 +0000201 auto* ref = TypeOf(acc)->As<sem::Reference>();
202 EXPECT_TRUE(ref->StoreType()->Is<sem::F32>());
Antonio Maioranodfeaf2902022-06-24 20:34:00 +0000203
204 auto idx_sem = Sem().Get(acc);
205 ASSERT_NE(idx_sem, nullptr);
206 EXPECT_EQ(idx_sem->Index()->Declaration(), acc->index);
207 EXPECT_EQ(idx_sem->Object()->Declaration(), acc->object);
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000208}
209
Ben Clayton49a09142022-05-31 15:22:21 +0000210TEST_F(ResolverIndexAccessorTest, Array_Literal_i32) {
Ben Clayton01208e72022-06-25 08:12:59 +0000211 GlobalVar("my_var", ty.array<f32, 3>(), ast::StorageClass::kPrivate);
Ben Clayton49a09142022-05-31 15:22:21 +0000212 auto* acc = IndexAccessor("my_var", 2_i);
dan sinclair41e4d9a2022-05-01 14:40:55 +0000213 WrapInFunction(acc);
dan sinclair41e4d9a2022-05-01 14:40:55 +0000214 EXPECT_TRUE(r()->Resolve()) << r()->error();
dan sinclair41e4d9a2022-05-01 14:40:55 +0000215 ASSERT_NE(TypeOf(acc), nullptr);
dan sinclair41e4d9a2022-05-01 14:40:55 +0000216 auto* ref = TypeOf(acc)->As<sem::Reference>();
Ben Clayton49a09142022-05-31 15:22:21 +0000217 ASSERT_NE(ref, nullptr);
218 EXPECT_TRUE(ref->StoreType()->Is<sem::F32>());
Antonio Maioranodfeaf2902022-06-24 20:34:00 +0000219
220 auto idx_sem = Sem().Get(acc);
221 ASSERT_NE(idx_sem, nullptr);
222 EXPECT_EQ(idx_sem->Index()->Declaration(), acc->index);
223 EXPECT_EQ(idx_sem->Object()->Declaration(), acc->object);
Ben Clayton49a09142022-05-31 15:22:21 +0000224}
225
226TEST_F(ResolverIndexAccessorTest, Array_Literal_u32) {
Ben Clayton01208e72022-06-25 08:12:59 +0000227 GlobalVar("my_var", ty.array<f32, 3>(), ast::StorageClass::kPrivate);
Ben Clayton49a09142022-05-31 15:22:21 +0000228 auto* acc = IndexAccessor("my_var", 2_u);
229 WrapInFunction(acc);
230 EXPECT_TRUE(r()->Resolve()) << r()->error();
231 ASSERT_NE(TypeOf(acc), nullptr);
232 auto* ref = TypeOf(acc)->As<sem::Reference>();
233 ASSERT_NE(ref, nullptr);
234 EXPECT_TRUE(ref->StoreType()->Is<sem::F32>());
Antonio Maioranodfeaf2902022-06-24 20:34:00 +0000235
236 auto idx_sem = Sem().Get(acc);
237 ASSERT_NE(idx_sem, nullptr);
238 EXPECT_EQ(idx_sem->Index()->Declaration(), acc->index);
239 EXPECT_EQ(idx_sem->Object()->Declaration(), acc->object);
Ben Clayton49a09142022-05-31 15:22:21 +0000240}
241
242TEST_F(ResolverIndexAccessorTest, Array_Literal_AInt) {
Ben Clayton01208e72022-06-25 08:12:59 +0000243 GlobalVar("my_var", ty.array<f32, 3>(), ast::StorageClass::kPrivate);
Ben Clayton49a09142022-05-31 15:22:21 +0000244 auto* acc = IndexAccessor("my_var", 2_a);
245 WrapInFunction(acc);
246 EXPECT_TRUE(r()->Resolve()) << r()->error();
247 ASSERT_NE(TypeOf(acc), nullptr);
248 auto* ref = TypeOf(acc)->As<sem::Reference>();
249 ASSERT_NE(ref, nullptr);
dan sinclair41e4d9a2022-05-01 14:40:55 +0000250 EXPECT_TRUE(ref->StoreType()->Is<sem::F32>());
Antonio Maioranodfeaf2902022-06-24 20:34:00 +0000251
252 auto idx_sem = Sem().Get(acc);
253 ASSERT_NE(idx_sem, nullptr);
254 EXPECT_EQ(idx_sem->Index()->Declaration(), acc->index);
255 EXPECT_EQ(idx_sem->Object()->Declaration(), acc->object);
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000256}
257
258TEST_F(ResolverIndexAccessorTest, Alias_Array) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000259 auto* aary = Alias("myarrty", ty.array<f32, 3>());
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000260
Ben Clayton01208e72022-06-25 08:12:59 +0000261 GlobalVar("my_var", ty.Of(aary), ast::StorageClass::kPrivate);
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000262
Ben Clayton0ce9ab02022-05-05 20:23:40 +0000263 auto* acc = IndexAccessor("my_var", 2_i);
dan sinclair41e4d9a2022-05-01 14:40:55 +0000264 WrapInFunction(acc);
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000265
dan sinclair41e4d9a2022-05-01 14:40:55 +0000266 EXPECT_TRUE(r()->Resolve()) << r()->error();
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000267
dan sinclair41e4d9a2022-05-01 14:40:55 +0000268 ASSERT_NE(TypeOf(acc), nullptr);
269 ASSERT_TRUE(TypeOf(acc)->Is<sem::Reference>());
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000270
dan sinclair41e4d9a2022-05-01 14:40:55 +0000271 auto* ref = TypeOf(acc)->As<sem::Reference>();
272 EXPECT_TRUE(ref->StoreType()->Is<sem::F32>());
Antonio Maioranodfeaf2902022-06-24 20:34:00 +0000273
274 auto idx_sem = Sem().Get(acc);
275 ASSERT_NE(idx_sem, nullptr);
276 EXPECT_EQ(idx_sem->Index()->Declaration(), acc->index);
277 EXPECT_EQ(idx_sem->Object()->Declaration(), acc->object);
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000278}
279
280TEST_F(ResolverIndexAccessorTest, Array_Constant) {
Ben Clayton41486e12022-06-25 07:17:29 +0000281 GlobalLet("my_var", ty.array<f32, 3>(), array<f32, 3>());
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000282
Ben Clayton0ce9ab02022-05-05 20:23:40 +0000283 auto* acc = IndexAccessor("my_var", 2_i);
dan sinclair41e4d9a2022-05-01 14:40:55 +0000284 WrapInFunction(acc);
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000285
dan sinclair41e4d9a2022-05-01 14:40:55 +0000286 EXPECT_TRUE(r()->Resolve()) << r()->error();
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000287
dan sinclair41e4d9a2022-05-01 14:40:55 +0000288 ASSERT_NE(TypeOf(acc), nullptr);
289 EXPECT_TRUE(TypeOf(acc)->Is<sem::F32>());
Antonio Maioranodfeaf2902022-06-24 20:34:00 +0000290
291 auto idx_sem = Sem().Get(acc);
292 ASSERT_NE(idx_sem, nullptr);
293 EXPECT_EQ(idx_sem->Index()->Declaration(), acc->index);
294 EXPECT_EQ(idx_sem->Object()->Declaration(), acc->object);
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000295}
296
297TEST_F(ResolverIndexAccessorTest, Array_Dynamic_I32) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000298 // let a : array<f32, 3> = 0;
299 // var idx : i32 = 0;
300 // var f : f32 = a[idx];
301 auto* a = Let("a", ty.array<f32, 3>(), array<f32, 3>());
302 auto* idx = Var("idx", ty.i32(), Construct(ty.i32()));
Antonio Maioranodfeaf2902022-06-24 20:34:00 +0000303 auto* acc = IndexAccessor("a", Expr(Source{{12, 34}}, idx));
304 auto* f = Var("f", ty.f32(), acc);
Ben Clayton7164b972022-06-15 10:02:37 +0000305 Func("my_func", {}, ty.void_(),
dan sinclair41e4d9a2022-05-01 14:40:55 +0000306 {
307 Decl(a),
308 Decl(idx),
309 Decl(f),
Ben Clayton7164b972022-06-15 10:02:37 +0000310 });
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000311
dan sinclair41e4d9a2022-05-01 14:40:55 +0000312 EXPECT_TRUE(r()->Resolve());
313 EXPECT_EQ(r()->error(), "");
Antonio Maioranodfeaf2902022-06-24 20:34:00 +0000314
315 auto idx_sem = Sem().Get(acc);
316 ASSERT_NE(idx_sem, nullptr);
317 EXPECT_EQ(idx_sem->Index()->Declaration(), acc->index);
318 EXPECT_EQ(idx_sem->Object()->Declaration(), acc->object);
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000319}
320
321TEST_F(ResolverIndexAccessorTest, Array_Literal_F32) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000322 // let a : array<f32, 3>;
323 // var f : f32 = a[2.0f];
324 auto* a = Let("a", ty.array<f32, 3>(), array<f32, 3>());
Ben Clayton0a3cda92022-05-10 17:30:15 +0000325 auto* f = Var("a_2", ty.f32(), IndexAccessor("a", Expr(Source{{12, 34}}, 2_f)));
Ben Clayton7164b972022-06-15 10:02:37 +0000326 Func("my_func", {}, ty.void_(),
dan sinclair41e4d9a2022-05-01 14:40:55 +0000327 {
328 Decl(a),
329 Decl(f),
Ben Clayton7164b972022-06-15 10:02:37 +0000330 });
dan sinclair41e4d9a2022-05-01 14:40:55 +0000331 EXPECT_FALSE(r()->Resolve());
332 EXPECT_EQ(r()->error(), "12:34 error: index must be of type 'i32' or 'u32', found: 'f32'");
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000333}
334
335TEST_F(ResolverIndexAccessorTest, Array_Literal_I32) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000336 // let a : array<f32, 3>;
Ben Clayton0ce9ab02022-05-05 20:23:40 +0000337 // var f : f32 = a[2i];
dan sinclair41e4d9a2022-05-01 14:40:55 +0000338 auto* a = Let("a", ty.array<f32, 3>(), array<f32, 3>());
Antonio Maioranodfeaf2902022-06-24 20:34:00 +0000339 auto* acc = IndexAccessor("a", 2_i);
340 auto* f = Var("a_2", ty.f32(), acc);
Ben Clayton7164b972022-06-15 10:02:37 +0000341 Func("my_func", {}, ty.void_(),
dan sinclair41e4d9a2022-05-01 14:40:55 +0000342 {
343 Decl(a),
344 Decl(f),
Ben Clayton7164b972022-06-15 10:02:37 +0000345 });
dan sinclair41e4d9a2022-05-01 14:40:55 +0000346 EXPECT_TRUE(r()->Resolve()) << r()->error();
Antonio Maioranodfeaf2902022-06-24 20:34:00 +0000347
348 auto idx_sem = Sem().Get(acc);
349 ASSERT_NE(idx_sem, nullptr);
350 EXPECT_EQ(idx_sem->Index()->Declaration(), acc->index);
351 EXPECT_EQ(idx_sem->Object()->Declaration(), acc->object);
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000352}
353
Ben Clayton49a09142022-05-31 15:22:21 +0000354TEST_F(ResolverIndexAccessorTest, Expr_Deref_FuncGoodParent) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000355 // fn func(p: ptr<function, vec4<f32>>) -> f32 {
356 // let idx: u32 = u32();
357 // let x: f32 = (*p)[idx];
358 // return x;
359 // }
360 auto* p = Param("p", ty.pointer(ty.vec4<f32>(), ast::StorageClass::kFunction));
361 auto* idx = Let("idx", ty.u32(), Construct(ty.u32()));
362 auto* star_p = Deref(p);
Antonio Maioranodfeaf2902022-06-24 20:34:00 +0000363 auto* acc = IndexAccessor(Source{{12, 34}}, star_p, idx);
364 auto* x = Var("x", ty.f32(), acc);
dan sinclair41e4d9a2022-05-01 14:40:55 +0000365 Func("func", {p}, ty.f32(), {Decl(idx), Decl(x), Return(x)});
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000366
dan sinclair41e4d9a2022-05-01 14:40:55 +0000367 EXPECT_TRUE(r()->Resolve()) << r()->error();
Antonio Maioranodfeaf2902022-06-24 20:34:00 +0000368
369 auto idx_sem = Sem().Get(acc);
370 ASSERT_NE(idx_sem, nullptr);
371 EXPECT_EQ(idx_sem->Index()->Declaration(), acc->index);
372 EXPECT_EQ(idx_sem->Object()->Declaration(), acc->object);
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000373}
374
Ben Clayton49a09142022-05-31 15:22:21 +0000375TEST_F(ResolverIndexAccessorTest, Expr_Deref_FuncBadParent) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000376 // fn func(p: ptr<function, vec4<f32>>) -> f32 {
377 // let idx: u32 = u32();
378 // let x: f32 = *p[idx];
379 // return x;
380 // }
381 auto* p = Param("p", ty.pointer(ty.vec4<f32>(), ast::StorageClass::kFunction));
382 auto* idx = Let("idx", ty.u32(), Construct(ty.u32()));
383 auto* accessor_expr = IndexAccessor(Source{{12, 34}}, p, idx);
384 auto* star_p = Deref(accessor_expr);
385 auto* x = Var("x", ty.f32(), star_p);
386 Func("func", {p}, ty.f32(), {Decl(idx), Decl(x), Return(x)});
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000387
dan sinclair41e4d9a2022-05-01 14:40:55 +0000388 EXPECT_FALSE(r()->Resolve());
389 EXPECT_EQ(r()->error(),
390 "12:34 error: cannot index type 'ptr<function, vec4<f32>, read_write>'");
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000391}
392
393TEST_F(ResolverIndexAccessorTest, Exr_Deref_BadParent) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000394 // var param: vec4<f32>
395 // let x: f32 = *(&param)[0];
396 auto* param = Var("param", ty.vec4<f32>());
397 auto* idx = Var("idx", ty.u32(), Construct(ty.u32()));
398 auto* addressOf_expr = AddressOf(param);
399 auto* accessor_expr = IndexAccessor(Source{{12, 34}}, addressOf_expr, idx);
400 auto* star_p = Deref(accessor_expr);
401 auto* x = Var("x", ty.f32(), star_p);
402 WrapInFunction(param, idx, x);
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000403
dan sinclair41e4d9a2022-05-01 14:40:55 +0000404 EXPECT_FALSE(r()->Resolve());
405 EXPECT_EQ(r()->error(),
406 "12:34 error: cannot index type 'ptr<function, vec4<f32>, read_write>'");
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000407}
408
409} // namespace
dan sinclaird2093792022-04-07 17:45:45 +0000410} // namespace tint::resolver