sem::StructMember: Add Type()

Once the AST switches to pure ast::Type nodes, we need a way to fetch the semantic type for a structure member.

Bug: tint:724
Change-Id: I4b55c1ec0220e29ca4ff3131cf2d41409821a538
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/49347
Commit-Queue: Ben Clayton <bclayton@chromium.org>
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
diff --git a/src/resolver/resolver.cc b/src/resolver/resolver.cc
index 599205e..c4588cd 100644
--- a/src/resolver/resolver.cc
+++ b/src/resolver/resolver.cc
@@ -2392,10 +2392,12 @@
   for (auto* member : str->impl()->members()) {
     Mark(member);
 
+    auto type = member->type();
+
     // First check the member type is legal
-    if (!IsStorable(member->type())) {
+    if (!IsStorable(type)) {
       builder_->Diagnostics().add_error(
-          std::string(member->type()->FriendlyName(builder_->Symbols())) +
+          std::string(type->FriendlyName(builder_->Symbols())) +
           " cannot be used as the type of a structure member");
       return nullptr;
     }
@@ -2403,7 +2405,7 @@
     uint32_t offset = struct_size;
     uint32_t align = 0;
     uint32_t size = 0;
-    if (!DefaultAlignAndSize(member->type(), align, size, member->source())) {
+    if (!DefaultAlignAndSize(type, align, size, member->source())) {
       return nullptr;
     }
 
@@ -2455,7 +2457,7 @@
     offset = utils::RoundUp(align, offset);
 
     auto* sem_member =
-        builder_->create<sem::StructMember>(member, offset, align, size);
+        builder_->create<sem::StructMember>(member, type, offset, align, size);
     builder_->Sem().Add(member, sem_member);
     sem_members.emplace_back(sem_member);
 
diff --git a/src/resolver/resolver_test.cc b/src/resolver/resolver_test.cc
index 2445077..8ae5475 100644
--- a/src/resolver/resolver_test.cc
+++ b/src/resolver/resolver_test.cc
@@ -892,13 +892,10 @@
 
   auto* ptr = TypeOf(mem)->As<sem::Pointer>();
   EXPECT_TRUE(ptr->type()->Is<sem::F32>());
-  ASSERT_TRUE(Sem().Get(mem)->Is<sem::StructMemberAccess>());
-  EXPECT_EQ(Sem()
-                .Get(mem)
-                ->As<sem::StructMemberAccess>()
-                ->Member()
-                ->Declaration()
-                ->symbol(),
+  auto* sma = Sem().Get(mem)->As<sem::StructMemberAccess>();
+  ASSERT_NE(sma, nullptr);
+  EXPECT_EQ(sma->Member()->Type(), ty.f32());
+  EXPECT_EQ(sma->Member()->Declaration()->symbol(),
             Symbols().Get("second_member"));
 }
 
@@ -918,7 +915,9 @@
 
   auto* ptr = TypeOf(mem)->As<sem::Pointer>();
   EXPECT_TRUE(ptr->type()->Is<sem::F32>());
-  ASSERT_TRUE(Sem().Get(mem)->Is<sem::StructMemberAccess>());
+  auto* sma = Sem().Get(mem)->As<sem::StructMemberAccess>();
+  ASSERT_NE(sma, nullptr);
+  EXPECT_EQ(sma->Member()->Type(), ty.f32());
 }
 
 TEST_F(ResolverTest, Expr_MemberAccessor_VectorSwizzle) {
diff --git a/src/sem/struct.cc b/src/sem/struct.cc
index 94212eb..85afa68 100644
--- a/src/sem/struct.cc
+++ b/src/sem/struct.cc
@@ -50,10 +50,15 @@
 }
 
 StructMember::StructMember(ast::StructMember* declaration,
+                           sem::Type* type,
                            uint32_t offset,
                            uint32_t align,
                            uint32_t size)
-    : declaration_(declaration), offset_(offset), align_(align), size_(size) {}
+    : declaration_(declaration),
+      type_(type),
+      offset_(offset),
+      align_(align),
+      size_(size) {}
 
 StructMember::~StructMember() = default;
 
diff --git a/src/sem/struct.h b/src/sem/struct.h
index 473775b..1c1d1a8 100644
--- a/src/sem/struct.h
+++ b/src/sem/struct.h
@@ -36,6 +36,7 @@
 // Forward declarations
 class StructType;
 class StructMember;
+class Type;
 
 /// A vector of StructMember pointers.
 using StructMemberList = std::vector<const StructMember*>;
@@ -141,10 +142,12 @@
  public:
   /// Constructor
   /// @param declaration the AST declaration node
+  /// @param type the type of the member
   /// @param offset the byte offset from the base of the structure
   /// @param align the byte alignment of the member
   /// @param size the byte size of the member
   StructMember(ast::StructMember* declaration,
+               sem::Type* type,
                uint32_t offset,
                uint32_t align,
                uint32_t size);
@@ -155,6 +158,9 @@
   /// @returns the AST declaration node
   ast::StructMember* Declaration() const { return declaration_; }
 
+  /// @returns the type of the member
+  sem::Type* Type() const { return type_; }
+
   /// @returns byte offset from base of structure
   uint32_t Offset() const { return offset_; }
 
@@ -166,6 +172,7 @@
 
  private:
   ast::StructMember* const declaration_;
+  sem::Type* const type_;
   uint32_t const offset_;  // Byte offset from base of structure
   uint32_t const align_;   // Byte alignment of the member
   uint32_t const size_;    // Byte size of the member