Add Source to sem::StructMember

This CL adds a Source to the sem::StructMember. The uses of
member->Declaration()->source now use the source stored directly on the
struct member.

Bug: tint:1718
Change-Id: Ic97053dd3e0080f128ee411857512920d3940858
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/112446
Commit-Queue: Dan Sinclair <dsinclair@chromium.org>
Reviewed-by: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
diff --git a/src/tint/resolver/inferred_type_test.cc b/src/tint/resolver/inferred_type_test.cc
index d2f649b..29294ef 100644
--- a/src/tint/resolver/inferred_type_test.cc
+++ b/src/tint/resolver/inferred_type_test.cc
@@ -150,11 +150,12 @@
     auto* member = Member("x", ty.i32());
     auto* str = Structure("S", utils::Vector{member});
 
-    auto* expected_type = create<sem::Struct>(
-        str, str->name,
-        sem::StructMemberList{create<sem::StructMember>(member, member->symbol, create<sem::I32>(),
-                                                        0u, 0u, 0u, 4u, std::nullopt)},
-        0u, 4u, 4u);
+    auto* expected_type =
+        create<sem::Struct>(str, str->name,
+                            sem::StructMemberList{create<sem::StructMember>(
+                                member, member->source, member->symbol, create<sem::I32>(), 0u, 0u,
+                                0u, 4u, std::nullopt)},
+                            0u, 4u, 4u);
 
     auto* ctor_expr = Construct(ty.Of(str));
 
diff --git a/src/tint/resolver/intrinsic_table.cc b/src/tint/resolver/intrinsic_table.cc
index a04eca4..2b9cfaf 100644
--- a/src/tint/resolver/intrinsic_table.cc
+++ b/src/tint/resolver/intrinsic_table.cc
@@ -809,6 +809,7 @@
         max_align = std::max(max_align, align);
         members.emplace_back(b.create<sem::StructMember>(
             /* declaration */ nullptr,
+            /* source */ Source{},
             /* name */ b.Sym(m.name),
             /* type */ m.type,
             /* index */ static_cast<uint32_t>(members.size()),
diff --git a/src/tint/resolver/resolver.cc b/src/tint/resolver/resolver.cc
index 5154cbe..9fbc7f0 100644
--- a/src/tint/resolver/resolver.cc
+++ b/src/tint/resolver/resolver.cc
@@ -3265,7 +3265,7 @@
         }
 
         auto* sem_member = builder_->create<sem::StructMember>(
-            member, member->symbol, type, static_cast<uint32_t>(sem_members.size()),
+            member, member->source, member->symbol, type, static_cast<uint32_t>(sem_members.size()),
             static_cast<uint32_t>(offset), static_cast<uint32_t>(align),
             static_cast<uint32_t>(size), location);
         builder_->Sem().Add(member, sem_member);
@@ -3296,7 +3296,7 @@
     for (size_t i = 0; i < sem_members.size(); i++) {
         auto* mem_type = sem_members[i]->Type();
         if (mem_type->Is<sem::Atomic>()) {
-            atomic_composite_info_.Add(out, &sem_members[i]->Declaration()->source);
+            atomic_composite_info_.Add(out, &sem_members[i]->Source());
             break;
         } else {
             if (auto found = atomic_composite_info_.Get(mem_type)) {
@@ -3621,7 +3621,7 @@
                 std::stringstream err;
                 err << "while analyzing structure member " << sem_.TypeNameOf(str) << "."
                     << builder_->Symbols().NameFor(member->Name());
-                AddNote(err.str(), decl->source);
+                AddNote(err.str(), member->Source());
                 return false;
             }
         }
diff --git a/src/tint/resolver/validator.cc b/src/tint/resolver/validator.cc
index 29ac69f..7ce0c48 100644
--- a/src/tint/resolver/validator.cc
+++ b/src/tint/resolver/validator.cc
@@ -461,7 +461,7 @@
                              " bytes, but '" + member_name_of(m) + "' is currently at offset " +
                              std::to_string(m->Offset()) + ". Consider setting @align(" +
                              std::to_string(required_align) + ") on this member",
-                         m->Declaration()->source);
+                         m->Source());
 
                 AddNote("see layout of struct:\n" + str->Layout(symbols_),
                         str->Declaration()->source);
@@ -488,7 +488,7 @@
                             std::to_string(prev_to_curr_offset) + " bytes between '" +
                             member_name_of(prev_member) + "' and '" + member_name_of(m) +
                             "'. Consider setting @align(16) on this member",
-                        m->Declaration()->source);
+                        m->Source());
 
                     AddNote("see layout of struct:\n" + str->Layout(symbols_),
                             str->Declaration()->source);
@@ -1228,8 +1228,8 @@
         if (auto* str = ty->As<sem::Struct>()) {
             for (auto* member : str->Members()) {
                 if (!validate_entry_point_attributes_inner(
-                        member->Declaration()->attributes, member->Type(),
-                        member->Declaration()->source, param_or_ret,
+                        member->Declaration()->attributes, member->Type(), member->Source(),
+                        param_or_ret,
                         /*is_struct_member*/ true, member->Location())) {
                     AddNote("while analyzing entry point '" + symbols_.NameFor(decl->symbol) + "'",
                             decl->source);
@@ -2027,7 +2027,7 @@
             if (r->IsRuntimeSized()) {
                 if (member != str->Members().back()) {
                     AddError("runtime arrays may only appear as the last member of a struct",
-                             member->Declaration()->source);
+                             member->Source());
                     return false;
                 }
             }
@@ -2039,7 +2039,7 @@
         } else if (!IsFixedFootprint(member->Type())) {
             AddError(
                 "a struct that contains a runtime array cannot be nested inside another struct",
-                member->Declaration()->source);
+                member->Source());
             return false;
         }
 
@@ -2058,7 +2058,7 @@
                     has_location = true;
                     TINT_ASSERT(Resolver, member->Location().has_value());
                     if (!LocationAttribute(location, member->Location().value(), member->Type(),
-                                           locations, stage, member->Declaration()->source)) {
+                                           locations, stage, member->Source())) {
                         return false;
                     }
                     return true;
diff --git a/src/tint/sem/struct.cc b/src/tint/sem/struct.cc
index 1634c39..18d796d 100644
--- a/src/tint/sem/struct.cc
+++ b/src/tint/sem/struct.cc
@@ -166,6 +166,7 @@
 }
 
 StructMember::StructMember(const ast::StructMember* declaration,
+                           tint::Source source,
                            Symbol name,
                            const sem::Type* type,
                            uint32_t index,
@@ -174,6 +175,7 @@
                            uint32_t size,
                            std::optional<uint32_t> location)
     : declaration_(declaration),
+      source_(source),
       name_(name),
       type_(type),
       index_(index),
diff --git a/src/tint/sem/struct.h b/src/tint/sem/struct.h
index 0ddfa23..1b59349 100644
--- a/src/tint/sem/struct.h
+++ b/src/tint/sem/struct.h
@@ -177,7 +177,8 @@
   public:
     /// Constructor
     /// @param declaration the AST declaration node
-    /// @param name the name of the structure
+    /// @param source the source of the struct member
+    /// @param name the name of the structure member
     /// @param type the type of the member
     /// @param index the index of the member in the structure
     /// @param offset the byte offset from the base of the structure
@@ -185,6 +186,7 @@
     /// @param size the byte size of the member
     /// @param location the location attribute, if present
     StructMember(const ast::StructMember* declaration,
+                 tint::Source source,
                  Symbol name,
                  const sem::Type* type,
                  uint32_t index,
@@ -199,6 +201,9 @@
     /// @returns the AST declaration node
     const ast::StructMember* Declaration() const { return declaration_; }
 
+    /// @returns the source the struct member
+    const tint::Source& Source() const { return source_; }
+
     /// @returns the name of the structure member
     Symbol Name() const { return name_; }
 
@@ -229,6 +234,7 @@
 
   private:
     const ast::StructMember* const declaration_;
+    const tint::Source source_;
     const Symbol name_;
     const sem::Struct* struct_;
     const sem::Type* type_;
diff --git a/src/tint/sem/type_test.cc b/src/tint/sem/type_test.cc
index aec9bde..43aff8b 100644
--- a/src/tint/sem/type_test.cc
+++ b/src/tint/sem/type_test.cc
@@ -49,6 +49,7 @@
                                                 StructMemberList{
                                                     create<StructMember>(
                                                         /* declaration */ nullptr,
+                                                        /* source */ Source{},
                                                         /* name */ Sym("x"),
                                                         /* type */ f32,
                                                         /* index */ 0u,
@@ -65,6 +66,7 @@
                                                 StructMemberList{
                                                     create<StructMember>(
                                                         /* declaration */ nullptr,
+                                                        /* source */ Source{},
                                                         /* name */ Sym("x"),
                                                         /* type */ f16,
                                                         /* index */ 0u,
@@ -81,6 +83,7 @@
                                          StructMemberList{
                                              create<StructMember>(
                                                  /* declaration */ nullptr,
+                                                 /* source */ Source{},
                                                  /* name */ Sym("x"),
                                                  /* type */ af,
                                                  /* index */ 0u,