writer/msl: Begin migration to ast::Types

The MSL writer doesn't really care much for ast::Types, so most of the work here is repointing the logic to fetch the resolved, semantic type.

Bug: tint:724
Change-Id: I017b83c9f661cc01cbde377991aab184c1733348
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/49529
Commit-Queue: Ben Clayton <bclayton@google.com>
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
diff --git a/src/writer/msl/generator_impl.cc b/src/writer/msl/generator_impl.cc
index e0378a0..1c239a7 100644
--- a/src/writer/msl/generator_impl.cc
+++ b/src/writer/msl/generator_impl.cc
@@ -886,10 +886,12 @@
 }
 
 bool GeneratorImpl::EmitTypeConstructor(ast::TypeConstructorExpression* expr) {
-  if (expr->type()->IsAnyOf<sem::ArrayType, sem::StructType>()) {
+  auto* type = TypeOf(expr);
+
+  if (type->IsAnyOf<sem::ArrayType, sem::StructType>()) {
     out_ << "{";
   } else {
-    if (!EmitType(expr->type(), "")) {
+    if (!EmitType(type, "")) {
       return false;
     }
     out_ << "(";
@@ -898,7 +900,7 @@
   // If the type constructor is empty then we need to construct with the zero
   // value for all components.
   if (expr->values().empty()) {
-    if (!EmitZeroValue(expr->type())) {
+    if (!EmitZeroValue(type)) {
       return false;
     }
   } else {
@@ -915,7 +917,7 @@
     }
   }
 
-  if (expr->type()->IsAnyOf<sem::ArrayType, sem::StructType>()) {
+  if (type->IsAnyOf<sem::ArrayType, sem::StructType>()) {
     out_ << "}";
   } else {
     out_ << ")";
@@ -923,7 +925,10 @@
   return true;
 }
 
-bool GeneratorImpl::EmitZeroValue(sem::Type* type) {
+bool GeneratorImpl::EmitZeroValue(typ::Type type) {
+  if (!type.sem) {
+    type.sem = program_->Sem().Get(type.ast);
+  }
   if (type->Is<sem::Bool>()) {
     out_ << "false";
   } else if (type->Is<sem::F32>()) {
@@ -1891,7 +1896,11 @@
   return true;
 }
 
-bool GeneratorImpl::EmitType(sem::Type* type, const std::string& name) {
+bool GeneratorImpl::EmitType(typ::Type type, const std::string& name) {
+  if (!type.sem) {
+    type.sem = program_->Sem().Get(type.ast);
+  }
+
   std::string access_str = "";
   if (auto* ac = type->As<sem::AccessControl>()) {
     if (ac->access_control() == ast::AccessControl::kReadOnly) {
@@ -2025,7 +2034,11 @@
   return true;
 }
 
-bool GeneratorImpl::EmitPackedType(sem::Type* type, const std::string& name) {
+bool GeneratorImpl::EmitPackedType(typ::Type type, const std::string& name) {
+  if (!type.sem) {
+    type.sem = program_->Sem().Get(type.ast);
+  }
+
   if (auto* alias = type->As<sem::Alias>()) {
     return EmitPackedType(alias->type(), name);
   }
@@ -2077,16 +2090,11 @@
 
   increment_indent();
   uint32_t msl_offset = 0;
-  for (auto* mem : str->impl()->members()) {
+  for (auto* mem : sem_str->Members()) {
     make_indent();
 
-    auto* sem_mem = program_->Sem().Get(mem);
-    if (!sem_mem) {
-      TINT_ICE(diagnostics_) << "struct member missing semantic info";
-      return false;
-    }
-
-    auto wgsl_offset = sem_mem->Offset();
+    auto name = program_->Symbols().NameFor(mem->Declaration()->symbol());
+    auto wgsl_offset = mem->Offset();
 
     if (is_host_shareable) {
       if (wgsl_offset < msl_offset) {
@@ -2107,25 +2115,24 @@
 
       add_byte_offset_comment(msl_offset);
 
-      if (!EmitPackedType(mem->type(),
-                          program_->Symbols().NameFor(mem->symbol()))) {
+      if (!EmitPackedType(mem->Type(), name)) {
         return false;
       }
     } else {
-      if (!EmitType(mem->type(), program_->Symbols().NameFor(mem->symbol()))) {
+      if (!EmitType(mem->Type(), name)) {
         return false;
       }
     }
 
-    auto* ty = mem->type()->UnwrapAliasIfNeeded();
+    auto* ty = mem->Type()->UnwrapAliasIfNeeded();
 
     // Array member name will be output with the type
     if (!ty->Is<sem::ArrayType>()) {
-      out_ << " " << program_->Symbols().NameFor(mem->symbol());
+      out_ << " " << name;
     }
 
     // Emit decorations
-    for (auto* deco : mem->decorations()) {
+    for (auto* deco : mem->Declaration()->decorations()) {
       if (auto* builtin = deco->As<ast::BuiltinDecoration>()) {
         auto attr = builtin_to_attribute(builtin->value());
         if (attr.empty()) {
@@ -2163,9 +2170,9 @@
       // Calculate new MSL offset
       auto size_align = MslPackedTypeSizeAndAlign(ty);
       if (msl_offset % size_align.align) {
-        TINT_ICE(diagnostics_) << "Misaligned MSL structure member "
-                               << ty->FriendlyName(program_->Symbols()) << " "
-                               << program_->Symbols().NameFor(mem->symbol());
+        TINT_ICE(diagnostics_)
+            << "Misaligned MSL structure member "
+            << ty->FriendlyName(program_->Symbols()) << " " << name;
         return false;
       }
       msl_offset += size_align.size;
diff --git a/src/writer/msl/generator_impl.h b/src/writer/msl/generator_impl.h
index ad74cb0..39974c5 100644
--- a/src/writer/msl/generator_impl.h
+++ b/src/writer/msl/generator_impl.h
@@ -195,14 +195,14 @@
   /// @param type the type to generate
   /// @param name the name of the variable, only used for array emission
   /// @returns true if the type is emitted
-  bool EmitType(sem::Type* type, const std::string& name);
+  bool EmitType(typ::Type type, const std::string& name);
   /// Handles generating an MSL-packed storage type.
   /// If the type does not have a packed form, the standard non-packed form is
   /// emitted.
   /// @param type the type to generate
   /// @param name the name of the variable, only used for array emission
   /// @returns true if the type is emitted
-  bool EmitPackedType(sem::Type* type, const std::string& name);
+  bool EmitPackedType(typ::Type type, const std::string& name);
   /// Handles generating a struct declaration
   /// @param str the struct to generate
   /// @returns true if the struct is emitted
@@ -227,7 +227,7 @@
   /// Emits the zero value for the given type
   /// @param type the type to emit the value for
   /// @returns true if the zero value was successfully emitted.
-  bool EmitZeroValue(sem::Type* type);
+  bool EmitZeroValue(typ::Type type);
 
   /// Determines if the function needs the input struct passed to it.
   /// @param func the function to check
@@ -273,6 +273,12 @@
     return program_->TypeOf(expr);
   }
 
+  /// @returns the resolved type of the ast::Type `type`
+  /// @param type the type
+  const sem::Type* TypeOf(ast::Type* type) const {
+    return program_->TypeOf(type);
+  }
+
   // A pair of byte size and alignment `uint32_t`s.
   struct SizeAndAlign {
     uint32_t size;
diff --git a/src/writer/msl/generator_impl_binary_test.cc b/src/writer/msl/generator_impl_binary_test.cc
index fb8ae0f..431c7e7 100644
--- a/src/writer/msl/generator_impl_binary_test.cc
+++ b/src/writer/msl/generator_impl_binary_test.cc
@@ -31,13 +31,15 @@
 TEST_P(MslBinaryTest, Emit) {
   auto params = GetParam();
 
-  auto* type = ((params.op == ast::BinaryOp::kLogicalAnd) ||
-                (params.op == ast::BinaryOp::kLogicalOr))
-                   ? static_cast<sem::Type*>(ty.bool_())
-                   : static_cast<sem::Type*>(ty.u32());
+  auto type = [&]() {
+    return ((params.op == ast::BinaryOp::kLogicalAnd) ||
+            (params.op == ast::BinaryOp::kLogicalOr))
+               ? static_cast<typ::Type>(ty.bool_())
+               : static_cast<typ::Type>(ty.u32());
+  };
 
-  auto* left = Var("left", type, ast::StorageClass::kFunction);
-  auto* right = Var("right", type, ast::StorageClass::kFunction);
+  auto* left = Var("left", type(), ast::StorageClass::kFunction);
+  auto* right = Var("right", type(), ast::StorageClass::kFunction);
 
   auto* expr =
       create<ast::BinaryExpression>(params.op, Expr("left"), Expr("right"));
diff --git a/src/writer/msl/generator_impl_type_test.cc b/src/writer/msl/generator_impl_type_test.cc
index ff7e71d..901cfbc 100644
--- a/src/writer/msl/generator_impl_type_test.cc
+++ b/src/writer/msl/generator_impl_type_test.cc
@@ -602,7 +602,7 @@
 }
 
 TEST_F(MslGeneratorImplTest, EmitType_U32) {
-  auto u32 = ty.u32();
+  auto* u32 = create<sem::U32>();
 
   GeneratorImpl& gen = Build();
 
@@ -715,11 +715,12 @@
                         "texturecube_array<float, access::sample>"}));
 
 TEST_F(MslGeneratorImplTest, Emit_TypeMultisampledTexture) {
-  sem::MultisampledTexture s(ast::TextureDimension::k2d, ty.u32());
+  auto* u32 = create<sem::U32>();
+  auto* ms = create<sem::MultisampledTexture>(ast::TextureDimension::k2d, u32);
 
   GeneratorImpl& gen = Build();
 
-  ASSERT_TRUE(gen.EmitType(&s, "")) << gen.error();
+  ASSERT_TRUE(gen.EmitType(ms, "")) << gen.error();
   EXPECT_EQ(gen.result(), "texture2d_ms<uint, access::sample>");
 }