tint: Add sem::IndexAccessorExpression

Also store expression object in MemberAccessorExpression, as well as the
struct on sem::StructMember.

These are used to implement spir-v reader atomics in a follow-up CL.

Bug: tint:1441
Change-Id: Iea49cfb7f9d2e7898d89d2dac6a16a14022c546f
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/94523
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Antonio Maiorano <amaiorano@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
diff --git a/src/tint/resolver/array_accessor_test.cc b/src/tint/resolver/array_accessor_test.cc
index 535d1ff..0c0ee47 100644
--- a/src/tint/resolver/array_accessor_test.cc
+++ b/src/tint/resolver/array_accessor_test.cc
@@ -16,6 +16,7 @@
 
 #include "gmock/gmock.h"
 #include "src/tint/resolver/resolver_test_helper.h"
+#include "src/tint/sem/index_accessor_expression.h"
 #include "src/tint/sem/reference.h"
 
 using namespace tint::number_suffixes;  // NOLINT
@@ -41,6 +42,11 @@
     WrapInFunction(Decl(idx), acc);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+    auto idx_sem = Sem().Get(acc);
+    ASSERT_NE(idx_sem, nullptr);
+    EXPECT_EQ(idx_sem->Index()->Declaration(), acc->index);
+    EXPECT_EQ(idx_sem->Object()->Declaration(), acc->object);
 }
 
 TEST_F(ResolverIndexAccessorTest, Matrix_BothDimensions_Dynamic_Ref) {
@@ -51,6 +57,11 @@
     WrapInFunction(Decl(idx), Decl(idy), acc);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+    auto idx_sem = Sem().Get(acc);
+    ASSERT_NE(idx_sem, nullptr);
+    EXPECT_EQ(idx_sem->Index()->Declaration(), acc->index);
+    EXPECT_EQ(idx_sem->Object()->Declaration(), acc->object);
 }
 
 TEST_F(ResolverIndexAccessorTest, Matrix_Dynamic) {
@@ -61,6 +72,11 @@
 
     EXPECT_TRUE(r()->Resolve());
     EXPECT_EQ(r()->error(), "");
+
+    auto idx_sem = Sem().Get(acc);
+    ASSERT_NE(idx_sem, nullptr);
+    EXPECT_EQ(idx_sem->Index()->Declaration(), acc->index);
+    EXPECT_EQ(idx_sem->Object()->Declaration(), acc->object);
 }
 
 TEST_F(ResolverIndexAccessorTest, Matrix_XDimension_Dynamic) {
@@ -71,6 +87,11 @@
 
     EXPECT_TRUE(r()->Resolve());
     EXPECT_EQ(r()->error(), "");
+
+    auto idx_sem = Sem().Get(acc);
+    ASSERT_NE(idx_sem, nullptr);
+    EXPECT_EQ(idx_sem->Index()->Declaration(), acc->index);
+    EXPECT_EQ(idx_sem->Object()->Declaration(), acc->object);
 }
 
 TEST_F(ResolverIndexAccessorTest, Matrix_BothDimension_Dynamic) {
@@ -81,6 +102,11 @@
 
     EXPECT_TRUE(r()->Resolve());
     EXPECT_EQ(r()->error(), "");
+
+    auto idx_sem = Sem().Get(acc);
+    ASSERT_NE(idx_sem, nullptr);
+    EXPECT_EQ(idx_sem->Index()->Declaration(), acc->index);
+    EXPECT_EQ(idx_sem->Object()->Declaration(), acc->object);
 }
 
 TEST_F(ResolverIndexAccessorTest, Matrix) {
@@ -97,6 +123,11 @@
     auto* ref = TypeOf(acc)->As<sem::Reference>();
     ASSERT_TRUE(ref->StoreType()->Is<sem::Vector>());
     EXPECT_EQ(ref->StoreType()->As<sem::Vector>()->Width(), 3u);
+
+    auto idx_sem = Sem().Get(acc);
+    ASSERT_NE(idx_sem, nullptr);
+    EXPECT_EQ(idx_sem->Index()->Declaration(), acc->index);
+    EXPECT_EQ(idx_sem->Object()->Declaration(), acc->object);
 }
 
 TEST_F(ResolverIndexAccessorTest, Matrix_BothDimensions) {
@@ -112,6 +143,11 @@
 
     auto* ref = TypeOf(acc)->As<sem::Reference>();
     EXPECT_TRUE(ref->StoreType()->Is<sem::F32>());
+
+    auto idx_sem = Sem().Get(acc);
+    ASSERT_NE(idx_sem, nullptr);
+    EXPECT_EQ(idx_sem->Index()->Declaration(), acc->index);
+    EXPECT_EQ(idx_sem->Object()->Declaration(), acc->object);
 }
 
 TEST_F(ResolverIndexAccessorTest, Vector_F32) {
@@ -130,6 +166,11 @@
     WrapInFunction(Decl(idx), acc);
 
     EXPECT_TRUE(r()->Resolve());
+
+    auto idx_sem = Sem().Get(acc);
+    ASSERT_NE(idx_sem, nullptr);
+    EXPECT_EQ(idx_sem->Index()->Declaration(), acc->index);
+    EXPECT_EQ(idx_sem->Object()->Declaration(), acc->object);
 }
 
 TEST_F(ResolverIndexAccessorTest, Vector_Dynamic) {
@@ -139,6 +180,11 @@
     WrapInFunction(Decl(idx), acc);
 
     EXPECT_TRUE(r()->Resolve());
+
+    auto idx_sem = Sem().Get(acc);
+    ASSERT_NE(idx_sem, nullptr);
+    EXPECT_EQ(idx_sem->Index()->Declaration(), acc->index);
+    EXPECT_EQ(idx_sem->Object()->Declaration(), acc->object);
 }
 
 TEST_F(ResolverIndexAccessorTest, Vector) {
@@ -154,6 +200,11 @@
 
     auto* ref = TypeOf(acc)->As<sem::Reference>();
     EXPECT_TRUE(ref->StoreType()->Is<sem::F32>());
+
+    auto idx_sem = Sem().Get(acc);
+    ASSERT_NE(idx_sem, nullptr);
+    EXPECT_EQ(idx_sem->Index()->Declaration(), acc->index);
+    EXPECT_EQ(idx_sem->Object()->Declaration(), acc->object);
 }
 
 TEST_F(ResolverIndexAccessorTest, Array_Literal_i32) {
@@ -165,6 +216,11 @@
     auto* ref = TypeOf(acc)->As<sem::Reference>();
     ASSERT_NE(ref, nullptr);
     EXPECT_TRUE(ref->StoreType()->Is<sem::F32>());
+
+    auto idx_sem = Sem().Get(acc);
+    ASSERT_NE(idx_sem, nullptr);
+    EXPECT_EQ(idx_sem->Index()->Declaration(), acc->index);
+    EXPECT_EQ(idx_sem->Object()->Declaration(), acc->object);
 }
 
 TEST_F(ResolverIndexAccessorTest, Array_Literal_u32) {
@@ -176,6 +232,11 @@
     auto* ref = TypeOf(acc)->As<sem::Reference>();
     ASSERT_NE(ref, nullptr);
     EXPECT_TRUE(ref->StoreType()->Is<sem::F32>());
+
+    auto idx_sem = Sem().Get(acc);
+    ASSERT_NE(idx_sem, nullptr);
+    EXPECT_EQ(idx_sem->Index()->Declaration(), acc->index);
+    EXPECT_EQ(idx_sem->Object()->Declaration(), acc->object);
 }
 
 TEST_F(ResolverIndexAccessorTest, Array_Literal_AInt) {
@@ -187,6 +248,11 @@
     auto* ref = TypeOf(acc)->As<sem::Reference>();
     ASSERT_NE(ref, nullptr);
     EXPECT_TRUE(ref->StoreType()->Is<sem::F32>());
+
+    auto idx_sem = Sem().Get(acc);
+    ASSERT_NE(idx_sem, nullptr);
+    EXPECT_EQ(idx_sem->Index()->Declaration(), acc->index);
+    EXPECT_EQ(idx_sem->Object()->Declaration(), acc->object);
 }
 
 TEST_F(ResolverIndexAccessorTest, Alias_Array) {
@@ -204,6 +270,11 @@
 
     auto* ref = TypeOf(acc)->As<sem::Reference>();
     EXPECT_TRUE(ref->StoreType()->Is<sem::F32>());
+
+    auto idx_sem = Sem().Get(acc);
+    ASSERT_NE(idx_sem, nullptr);
+    EXPECT_EQ(idx_sem->Index()->Declaration(), acc->index);
+    EXPECT_EQ(idx_sem->Object()->Declaration(), acc->object);
 }
 
 TEST_F(ResolverIndexAccessorTest, Array_Constant) {
@@ -216,6 +287,11 @@
 
     ASSERT_NE(TypeOf(acc), nullptr);
     EXPECT_TRUE(TypeOf(acc)->Is<sem::F32>());
+
+    auto idx_sem = Sem().Get(acc);
+    ASSERT_NE(idx_sem, nullptr);
+    EXPECT_EQ(idx_sem->Index()->Declaration(), acc->index);
+    EXPECT_EQ(idx_sem->Object()->Declaration(), acc->object);
 }
 
 TEST_F(ResolverIndexAccessorTest, Array_Dynamic_I32) {
@@ -224,7 +300,8 @@
     // var f : f32 = a[idx];
     auto* a = Let("a", ty.array<f32, 3>(), array<f32, 3>());
     auto* idx = Var("idx", ty.i32(), Construct(ty.i32()));
-    auto* f = Var("f", ty.f32(), IndexAccessor("a", Expr(Source{{12, 34}}, idx)));
+    auto* acc = IndexAccessor("a", Expr(Source{{12, 34}}, idx));
+    auto* f = Var("f", ty.f32(), acc);
     Func("my_func", {}, ty.void_(),
          {
              Decl(a),
@@ -234,6 +311,11 @@
 
     EXPECT_TRUE(r()->Resolve());
     EXPECT_EQ(r()->error(), "");
+
+    auto idx_sem = Sem().Get(acc);
+    ASSERT_NE(idx_sem, nullptr);
+    EXPECT_EQ(idx_sem->Index()->Declaration(), acc->index);
+    EXPECT_EQ(idx_sem->Object()->Declaration(), acc->object);
 }
 
 TEST_F(ResolverIndexAccessorTest, Array_Literal_F32) {
@@ -254,13 +336,19 @@
     // let a : array<f32, 3>;
     // var f : f32 = a[2i];
     auto* a = Let("a", ty.array<f32, 3>(), array<f32, 3>());
-    auto* f = Var("a_2", ty.f32(), IndexAccessor("a", 2_i));
+    auto* acc = IndexAccessor("a", 2_i);
+    auto* f = Var("a_2", ty.f32(), acc);
     Func("my_func", {}, ty.void_(),
          {
              Decl(a),
              Decl(f),
          });
     EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+    auto idx_sem = Sem().Get(acc);
+    ASSERT_NE(idx_sem, nullptr);
+    EXPECT_EQ(idx_sem->Index()->Declaration(), acc->index);
+    EXPECT_EQ(idx_sem->Object()->Declaration(), acc->object);
 }
 
 TEST_F(ResolverIndexAccessorTest, Expr_Deref_FuncGoodParent) {
@@ -272,11 +360,16 @@
     auto* p = Param("p", ty.pointer(ty.vec4<f32>(), ast::StorageClass::kFunction));
     auto* idx = Let("idx", ty.u32(), Construct(ty.u32()));
     auto* star_p = Deref(p);
-    auto* accessor_expr = IndexAccessor(Source{{12, 34}}, star_p, idx);
-    auto* x = Var("x", ty.f32(), accessor_expr);
+    auto* acc = IndexAccessor(Source{{12, 34}}, star_p, idx);
+    auto* x = Var("x", ty.f32(), acc);
     Func("func", {p}, ty.f32(), {Decl(idx), Decl(x), Return(x)});
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+    auto idx_sem = Sem().Get(acc);
+    ASSERT_NE(idx_sem, nullptr);
+    EXPECT_EQ(idx_sem->Index()->Declaration(), acc->index);
+    EXPECT_EQ(idx_sem->Object()->Declaration(), acc->object);
 }
 
 TEST_F(ResolverIndexAccessorTest, Expr_Deref_FuncBadParent) {