writer/hlsl: Begin migration to ast::Types

The HLSL 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.
Output for aliases has changed, as the semantic type resolves away aliases.

Bug: tint:724
Change-Id: I6eb9d5c2fbcd62eef0f9dd145360714db649e13f
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/49530
Commit-Queue: Ben Clayton <bclayton@google.com>
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
diff --git a/src/writer/hlsl/generator_impl.cc b/src/writer/hlsl/generator_impl.cc
index ffdef07..e4ed9fd 100644
--- a/src/writer/hlsl/generator_impl.cc
+++ b/src/writer/hlsl/generator_impl.cc
@@ -226,7 +226,8 @@
       return false;
     }
   } else {
-    diagnostics_.add_error("unknown constructed type: " + ty->type_name());
+    TINT_UNREACHABLE(diagnostics_)
+        << "constructed type: " << ty->TypeInfo().name;
     return false;
   }
 
@@ -252,14 +253,14 @@
 bool GeneratorImpl::EmitBitcast(std::ostream& pre,
                                 std::ostream& out,
                                 ast::BitcastExpression* expr) {
-  if (!expr->type()->is_integer_scalar() && !expr->type()->is_float_scalar()) {
-    diagnostics_.add_error("Unable to do bitcast to type " +
-                           expr->type()->type_name());
+  auto* type = TypeOf(expr);
+  if (!type->is_integer_scalar() && !type->is_float_scalar()) {
+    diagnostics_.add_error("Unable to do bitcast to type " + type->type_name());
     return false;
   }
 
   out << "as";
-  if (!EmitType(out, expr->type(), ast::StorageClass::kNone, "")) {
+  if (!EmitType(out, type, ast::StorageClass::kNone, "")) {
     return false;
   }
   out << "(";
@@ -1312,20 +1313,21 @@
 bool GeneratorImpl::EmitTypeConstructor(std::ostream& pre,
                                         std::ostream& out,
                                         ast::TypeConstructorExpression* expr) {
+  auto* type = TypeOf(expr);
+
   // If the type constructor is empty then we need to construct with the zero
   // value for all components.
   if (expr->values().empty()) {
-    return EmitZeroValue(out, expr->type());
+    return EmitZeroValue(out, type);
   }
 
-  bool brackets = expr->type()
-                      ->UnwrapAliasIfNeeded()
-                      ->IsAnyOf<sem::ArrayType, sem::StructType>();
+  bool brackets =
+      type->UnwrapAliasIfNeeded()->IsAnyOf<sem::ArrayType, sem::StructType>();
 
   if (brackets) {
     out << "{";
   } else {
-    if (!EmitType(out, expr->type(), ast::StorageClass::kNone, "")) {
+    if (!EmitType(out, type, ast::StorageClass::kNone, "")) {
       return false;
     }
     out << "(";
@@ -1578,27 +1580,27 @@
 }
 
 bool GeneratorImpl::EmitFunctionInternal(std::ostream& out,
-                                         ast::Function* func,
+                                         ast::Function* func_ast,
                                          bool emit_duplicate_functions,
                                          Symbol ep_sym) {
-  auto name = func->symbol().to_str();
+  auto* func = builder_.Sem().Get(func_ast);
 
-  if (!EmitType(out, func->return_type(), ast::StorageClass::kNone, "")) {
+  if (!EmitType(out, func->ReturnType(), ast::StorageClass::kNone, "")) {
     return false;
   }
 
   out << " ";
 
+  std::string name;
   if (emit_duplicate_functions) {
-    auto func_name = name;
     auto ep_name = ep_sym.to_str();
     // TODO(dsinclair): The SymbolToName should go away and just use
     // to_str() here when the conversion is complete.
-    name = generate_name(builder_.Symbols().NameFor(func->symbol()) + "_" +
+    name = generate_name(builder_.Symbols().NameFor(func_ast->symbol()) + "_" +
                          builder_.Symbols().NameFor(ep_sym));
-    ep_func_name_remapped_[ep_name + "_" + func_name] = name;
+    ep_func_name_remapped_[ep_name + "_" + func_ast->symbol().to_str()] = name;
   } else {
-    name = builder_.Symbols().NameFor(func->symbol());
+    name = builder_.Symbols().NameFor(func_ast->symbol());
   }
 
   out << name << "(";
@@ -1628,27 +1630,26 @@
     }
   }
 
-  for (auto* v : func->params()) {
+  for (auto* v : func->Parameters()) {
     if (!first) {
       out << ", ";
     }
     first = false;
 
-    auto* sem = builder_.Sem().Get(v);
-    auto* type = sem->Type();
+    auto* type = v->Type();
 
     // Note: WGSL only allows for StorageClass::kNone on parameters, however the
     // sanitizer transforms generates load / store functions for storage
     // buffers. These functions have a storage buffer parameter with
     // StorageClass::kStorage. This is required to correctly translate the
     // parameter to [RW]ByteAddressBuffer.
-    if (!EmitType(out, type, sem->StorageClass(),
-                  builder_.Symbols().NameFor(v->symbol()))) {
+    if (!EmitType(out, type, v->StorageClass(),
+                  builder_.Symbols().NameFor(v->Declaration()->symbol()))) {
       return false;
     }
     // Array name is output as part of the type
     if (!type->Is<sem::ArrayType>()) {
-      out << " " << builder_.Symbols().NameFor(v->symbol());
+      out << " " << builder_.Symbols().NameFor(v->Declaration()->symbol());
     }
   }
 
@@ -1656,7 +1657,7 @@
 
   current_ep_sym_ = ep_sym;
 
-  if (!EmitBlockAndNewline(out, func->body())) {
+  if (!EmitBlockAndNewline(out, func_ast->body())) {
     return false;
   }
 
@@ -1885,7 +1886,7 @@
     for (auto* var : func_sem->ReferencedModuleVariables()) {
       auto* decl = var->Declaration();
 
-      auto* unwrapped_type = var->DeclaredType()->UnwrapAll();
+      auto* unwrapped_type = var->Type()->UnwrapAll();
       if (!emitted_globals.emplace(decl->symbol()).second) {
         continue;  // Global already emitted
       }
@@ -1911,10 +1912,10 @@
       }
 
       auto name = builder_.Symbols().NameFor(decl->symbol());
-      if (!EmitType(out, var->DeclaredType(), var->StorageClass(), name)) {
+      if (!EmitType(out, var->Type(), var->StorageClass(), name)) {
         return false;
       }
-      if (!var->DeclaredType()->UnwrapAliasIfNeeded()->Is<sem::ArrayType>()) {
+      if (!var->Type()->UnwrapAliasIfNeeded()->Is<sem::ArrayType>()) {
         out << " " << name;
       }
 
@@ -2139,12 +2140,12 @@
   } else if (auto* str = type->As<sem::StructType>()) {
     out << "{";
     bool first = true;
-    for (auto* member : str->impl()->members()) {
+    for (auto* member : builder_.Sem().Get(str)->Members()) {
       if (!first) {
         out << ", ";
       }
       first = false;
-      if (!EmitZeroValue(out, member->type())) {
+      if (!EmitZeroValue(out, member->Type())) {
         return false;
       }
     }
@@ -2559,21 +2560,21 @@
   out << "struct " << name << " {" << std::endl;
 
   increment_indent();
-  for (auto* mem : str->impl()->members()) {
+  for (auto* mem : sem_str->Members()) {
     make_indent(out);
     // TODO(dsinclair): Handle [[offset]] annotation on structs
     // https://bugs.chromium.org/p/tint/issues/detail?id=184
 
-    if (!EmitType(out, mem->type(), ast::StorageClass::kNone,
-                  builder_.Symbols().NameFor(mem->symbol()))) {
+    auto mem_name = builder_.Symbols().NameFor(mem->Declaration()->symbol());
+    if (!EmitType(out, mem->Type(), ast::StorageClass::kNone, mem_name)) {
       return false;
     }
     // Array member name will be output with the type
-    if (!mem->type()->Is<sem::ArrayType>()) {
-      out << " " << builder_.Symbols().NameFor(mem->symbol());
+    if (!mem->Type()->Is<sem::ArrayType>()) {
+      out << " " << mem_name;
     }
 
-    for (auto* deco : mem->decorations()) {
+    for (auto* deco : mem->Declaration()->decorations()) {
       if (auto* location = deco->As<ast::LocationDecoration>()) {
         auto& pipeline_stage_uses =
             builder_.Sem().Get(str)->PipelineStageUses();
diff --git a/src/writer/hlsl/generator_impl.h b/src/writer/hlsl/generator_impl.h
index 0059fc0..2f7aab9 100644
--- a/src/writer/hlsl/generator_impl.h
+++ b/src/writer/hlsl/generator_impl.h
@@ -379,6 +379,12 @@
     return builder_.TypeOf(expr);
   }
 
+  /// @returns the resolved type of the ast::Type `type`
+  /// @param type the type
+  const sem::Type* TypeOf(ast::Type* type) const {
+    return builder_.TypeOf(type);
+  }
+
   ProgramBuilder builder_;
   Symbol current_ep_sym_;
   bool generating_entry_point_ = false;
diff --git a/src/writer/hlsl/generator_impl_alias_type_test.cc b/src/writer/hlsl/generator_impl_alias_type_test.cc
index f398d8c..b206b89 100644
--- a/src/writer/hlsl/generator_impl_alias_type_test.cc
+++ b/src/writer/hlsl/generator_impl_alias_type_test.cc
@@ -34,16 +34,6 @@
 )");
 }
 
-TEST_F(HlslGeneratorImplTest_Alias, EmitAlias_NameCollision) {
-  AST().AddConstructedType(ty.alias("float", ty.f32()));
-
-  GeneratorImpl& gen = SanitizeAndBuild();
-
-  ASSERT_TRUE(gen.Generate(out)) << gen.error();
-  EXPECT_THAT(result(), HasSubstr(R"(typedef float tint_symbol;
-)"));
-}
-
 TEST_F(HlslGeneratorImplTest_Alias, EmitAlias_Struct) {
   auto s = Structure("A", {
                               Member("a", ty.f32()),
diff --git a/src/writer/hlsl/generator_impl_member_accessor_test.cc b/src/writer/hlsl/generator_impl_member_accessor_test.cc
index 9b6d552..8ff9211 100644
--- a/src/writer/hlsl/generator_impl_member_accessor_test.cc
+++ b/src/writer/hlsl/generator_impl_member_accessor_test.cc
@@ -32,7 +32,7 @@
   return ty.i32();
 }
 inline typ::Type ty_u32(const ProgramBuilder::TypesBuilder& ty) {
-  return ty.u32();
+  return ty.builder->create<sem::U32>();
 }
 inline typ::Type ty_f32(const ProgramBuilder::TypesBuilder& ty) {
   return ty.f32();
@@ -250,15 +250,14 @@
 
   auto p = GetParam();
 
-  auto type = p.member_type(ty);
-
   SetupStorageBuffer({
       Member("a", ty.i32()),
-      Member("b", type),
+      Member("b", p.member_type(ty)),
   });
 
   SetupFunction({
-      Decl(Var("value", type, ast::StorageClass::kFunction, Construct(type))),
+      Decl(Var("value", p.member_type(ty), ast::StorageClass::kFunction,
+               Construct(p.member_type(ty)))),
       Assign(MemberAccessor("data", "b"), Expr("value")),
   });
 
diff --git a/src/writer/hlsl/generator_impl_workgroup_var_test.cc b/src/writer/hlsl/generator_impl_workgroup_var_test.cc
index ca73fdd..525adbe 100644
--- a/src/writer/hlsl/generator_impl_workgroup_var_test.cc
+++ b/src/writer/hlsl/generator_impl_workgroup_var_test.cc
@@ -49,7 +49,7 @@
   GeneratorImpl& gen = Build();
 
   ASSERT_TRUE(gen.Generate(out)) << gen.error();
-  EXPECT_THAT(result(), HasSubstr("groupshared F32 wg;\n"));
+  EXPECT_THAT(result(), HasSubstr("groupshared float wg;\n"));
 
   Validate();
 }