Add Source to sem::Struct

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

Bug: tint:1718
Change-Id: I860c67764f85d98b3f655247e18f93fa0fef9436
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/112447
Reviewed-by: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Dan Sinclair <dsinclair@chromium.org>
diff --git a/src/tint/resolver/inferred_type_test.cc b/src/tint/resolver/inferred_type_test.cc
index 29294ef..469a5e0 100644
--- a/src/tint/resolver/inferred_type_test.cc
+++ b/src/tint/resolver/inferred_type_test.cc
@@ -151,7 +151,7 @@
     auto* str = Structure("S", utils::Vector{member});
 
     auto* expected_type =
-        create<sem::Struct>(str, str->name,
+        create<sem::Struct>(str, str->source, str->name,
                             sem::StructMemberList{create<sem::StructMember>(
                                 member, member->source, member->symbol, create<sem::I32>(), 0u, 0u,
                                 0u, 4u, std::nullopt)},
diff --git a/src/tint/resolver/intrinsic_table.cc b/src/tint/resolver/intrinsic_table.cc
index 2b9cfaf..e58e980 100644
--- a/src/tint/resolver/intrinsic_table.cc
+++ b/src/tint/resolver/intrinsic_table.cc
@@ -823,6 +823,7 @@
     uint32_t size_with_padding = utils::RoundUp(max_align, offset);
     return b.create<sem::Struct>(
         /* declaration */ nullptr,
+        /* source */ Source{},
         /* name */ b.Sym(name),
         /* members */ members,
         /* align */ max_align,
diff --git a/src/tint/resolver/resolver.cc b/src/tint/resolver/resolver.cc
index e5b188c..3ad8661 100644
--- a/src/tint/resolver/resolver.cc
+++ b/src/tint/resolver/resolver.cc
@@ -3299,7 +3299,7 @@
     }
 
     auto* out = builder_->create<sem::Struct>(
-        str, str->name, sem_members, static_cast<uint32_t>(struct_align),
+        str, str->source, str->name, sem_members, static_cast<uint32_t>(struct_align),
         static_cast<uint32_t>(struct_size), static_cast<uint32_t>(size_no_padding));
 
     for (size_t i = 0; i < sem_members.size(); i++) {
diff --git a/src/tint/resolver/validator.cc b/src/tint/resolver/validator.cc
index 7ce0c48..83c8c78 100644
--- a/src/tint/resolver/validator.cc
+++ b/src/tint/resolver/validator.cc
@@ -446,8 +446,7 @@
 
             // Recurse into the member type.
             if (!AddressSpaceLayout(m->Type(), address_space, m->Declaration()->type->source)) {
-                AddNote("see layout of struct:\n" + str->Layout(symbols_),
-                        str->Declaration()->source);
+                AddNote("see layout of struct:\n" + str->Layout(symbols_), str->Source());
                 note_usage();
                 return false;
             }
@@ -463,12 +462,11 @@
                              std::to_string(required_align) + ") on this member",
                          m->Source());
 
-                AddNote("see layout of struct:\n" + str->Layout(symbols_),
-                        str->Declaration()->source);
+                AddNote("see layout of struct:\n" + str->Layout(symbols_), str->Source());
 
                 if (auto* member_str = m->Type()->As<sem::Struct>()) {
                     AddNote("and layout of struct member:\n" + member_str->Layout(symbols_),
-                            member_str->Declaration()->source);
+                            member_str->Source());
                 }
 
                 note_usage();
@@ -490,13 +488,12 @@
                             "'. Consider setting @align(16) on this member",
                         m->Source());
 
-                    AddNote("see layout of struct:\n" + str->Layout(symbols_),
-                            str->Declaration()->source);
+                    AddNote("see layout of struct:\n" + str->Layout(symbols_), str->Source());
 
                     auto* prev_member_str = prev_member->Type()->As<sem::Struct>();
                     AddNote("and layout of previous member struct:\n" +
                                 prev_member_str->Layout(symbols_),
-                            prev_member_str->Declaration()->source);
+                            prev_member_str->Source());
                     note_usage();
                     return false;
                 }
@@ -2017,7 +2014,7 @@
 
 bool Validator::Structure(const sem::Struct* str, ast::PipelineStage stage) const {
     if (str->Members().empty()) {
-        AddError("structures must have at least one member", str->Declaration()->source);
+        AddError("structures must have at least one member", str->Source());
         return false;
     }
 
diff --git a/src/tint/sem/struct.cc b/src/tint/sem/struct.cc
index 18d796d..c46e310 100644
--- a/src/tint/sem/struct.cc
+++ b/src/tint/sem/struct.cc
@@ -52,6 +52,7 @@
 }  // namespace
 
 Struct::Struct(const ast::Struct* declaration,
+               tint::Source source,
                Symbol name,
                StructMemberList members,
                uint32_t align,
@@ -59,6 +60,7 @@
                uint32_t size_no_padding)
     : Base(FlagsFrom(members)),
       declaration_(declaration),
+      source_(source),
       name_(name),
       members_(std::move(members)),
       align_(align),
diff --git a/src/tint/sem/struct.h b/src/tint/sem/struct.h
index 1b59349..831cf3e 100644
--- a/src/tint/sem/struct.h
+++ b/src/tint/sem/struct.h
@@ -57,6 +57,7 @@
   public:
     /// Constructor
     /// @param declaration the AST structure declaration
+    /// @param source the source of the structure
     /// @param name the name of the structure
     /// @param members the structure members
     /// @param align the byte alignment of the structure
@@ -64,6 +65,7 @@
     /// @param size_no_padding size of the members without the end of structure
     /// alignment padding
     Struct(const ast::Struct* declaration,
+           tint::Source source,
            Symbol name,
            StructMemberList members,
            uint32_t align,
@@ -83,6 +85,9 @@
     /// @returns the struct
     const ast::Struct* Declaration() const { return declaration_; }
 
+    /// @returns the source of the structure
+    tint::Source Source() const { return source_; }
+
     /// @returns the name of the structure
     Symbol Name() const { return name_; }
 
@@ -162,6 +167,7 @@
 
   private:
     ast::Struct const* const declaration_;
+    const tint::Source source_;
     const Symbol name_;
     const StructMemberList members_;
     const uint32_t align_;
diff --git a/src/tint/sem/struct_test.cc b/src/tint/sem/struct_test.cc
index a8b36ca..6a88307 100644
--- a/src/tint/sem/struct_test.cc
+++ b/src/tint/sem/struct_test.cc
@@ -26,8 +26,8 @@
     auto name = Sym("S");
     auto* impl = create<ast::Struct>(name, utils::Empty, utils::Empty);
     auto* ptr = impl;
-    auto* s = create<sem::Struct>(impl, impl->name, StructMemberList{}, 4u /* align */,
-                                  8u /* size */, 16u /* size_no_padding */);
+    auto* s = create<sem::Struct>(impl, impl->source, impl->name, StructMemberList{},
+                                  4u /* align */, 8u /* size */, 16u /* size_no_padding */);
     EXPECT_EQ(s->Declaration(), ptr);
     EXPECT_EQ(s->Align(), 4u);
     EXPECT_EQ(s->Size(), 8u);
@@ -36,22 +36,22 @@
 
 TEST_F(StructTest, Hash) {
     auto* a_impl = create<ast::Struct>(Sym("a"), utils::Empty, utils::Empty);
-    auto* a = create<sem::Struct>(a_impl, a_impl->name, StructMemberList{}, 4u /* align */,
-                                  4u /* size */, 4u /* size_no_padding */);
+    auto* a = create<sem::Struct>(a_impl, a_impl->source, a_impl->name, StructMemberList{},
+                                  4u /* align */, 4u /* size */, 4u /* size_no_padding */);
     auto* b_impl = create<ast::Struct>(Sym("b"), utils::Empty, utils::Empty);
-    auto* b = create<sem::Struct>(b_impl, b_impl->name, StructMemberList{}, 4u /* align */,
-                                  4u /* size */, 4u /* size_no_padding */);
+    auto* b = create<sem::Struct>(b_impl, b_impl->source, b_impl->name, StructMemberList{},
+                                  4u /* align */, 4u /* size */, 4u /* size_no_padding */);
 
     EXPECT_NE(a->Hash(), b->Hash());
 }
 
 TEST_F(StructTest, Equals) {
     auto* a_impl = create<ast::Struct>(Sym("a"), utils::Empty, utils::Empty);
-    auto* a = create<sem::Struct>(a_impl, a_impl->name, StructMemberList{}, 4u /* align */,
-                                  4u /* size */, 4u /* size_no_padding */);
+    auto* a = create<sem::Struct>(a_impl, a_impl->source, a_impl->name, StructMemberList{},
+                                  4u /* align */, 4u /* size */, 4u /* size_no_padding */);
     auto* b_impl = create<ast::Struct>(Sym("b"), utils::Empty, utils::Empty);
-    auto* b = create<sem::Struct>(b_impl, b_impl->name, StructMemberList{}, 4u /* align */,
-                                  4u /* size */, 4u /* size_no_padding */);
+    auto* b = create<sem::Struct>(b_impl, b_impl->source, b_impl->name, StructMemberList{},
+                                  4u /* align */, 4u /* size */, 4u /* size_no_padding */);
 
     EXPECT_TRUE(a->Equals(*a));
     EXPECT_FALSE(a->Equals(*b));
@@ -61,8 +61,8 @@
 TEST_F(StructTest, FriendlyName) {
     auto name = Sym("my_struct");
     auto* impl = create<ast::Struct>(name, utils::Empty, utils::Empty);
-    auto* s = create<sem::Struct>(impl, impl->name, StructMemberList{}, 4u /* align */,
-                                  4u /* size */, 4u /* size_no_padding */);
+    auto* s = create<sem::Struct>(impl, impl->source, impl->name, StructMemberList{},
+                                  4u /* align */, 4u /* size */, 4u /* size_no_padding */);
     EXPECT_EQ(s->FriendlyName(Symbols()), "my_struct");
 }
 
diff --git a/src/tint/sem/type_test.cc b/src/tint/sem/type_test.cc
index 43aff8b..db7616b 100644
--- a/src/tint/sem/type_test.cc
+++ b/src/tint/sem/type_test.cc
@@ -45,6 +45,7 @@
     const sem::Reference* ref_u32 =
         create<Reference>(u32, ast::AddressSpace::kPrivate, ast::Access::kReadWrite);
     const sem::Struct* str_f32 = create<Struct>(nullptr,
+                                                Source{},
                                                 Sym("str_f32"),
                                                 StructMemberList{
                                                     create<StructMember>(
@@ -62,6 +63,7 @@
                                                 /* size*/ 4u,
                                                 /* size_no_padding*/ 4u);
     const sem::Struct* str_f16 = create<Struct>(nullptr,
+                                                Source{},
                                                 Sym("str_f16"),
                                                 StructMemberList{
                                                     create<StructMember>(
@@ -79,6 +81,7 @@
                                                 /* size*/ 4u,
                                                 /* size_no_padding*/ 4u);
     sem::Struct* str_af = create<Struct>(nullptr,
+                                         Source{},
                                          Sym("str_af"),
                                          StructMemberList{
                                              create<StructMember>(
diff --git a/src/tint/transform/transform_test.cc b/src/tint/transform/transform_test.cc
index 4b8ad53..2a39094 100644
--- a/src/tint/transform/transform_test.cc
+++ b/src/tint/transform/transform_test.cc
@@ -122,8 +122,8 @@
 TEST_F(CreateASTTypeForTest, Struct) {
     auto* str = create([](ProgramBuilder& b) {
         auto* decl = b.Structure("S", {});
-        return b.create<sem::Struct>(decl, decl->name, sem::StructMemberList{}, 4u /* align */,
-                                     4u /* size */, 4u /* size_no_padding */);
+        return b.create<sem::Struct>(decl, decl->source, decl->name, sem::StructMemberList{},
+                                     4u /* align */, 4u /* size */, 4u /* size_no_padding */);
     });
     ASSERT_TRUE(str->Is<ast::TypeName>());
     EXPECT_EQ(ast_type_builder.Symbols().NameFor(str->As<ast::TypeName>()->name), "S");