ast::Module: Move ConstructedTypes() to typ::Type

And add a few additional helper methods.
Stepping stone to having the module only reference AST nodes.

Bug: tint:724
Change-Id: Ib321dadce5f739afe4f71cbafde9dd2d1c6431bb
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/49743
Commit-Queue: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
diff --git a/src/ast/module.cc b/src/ast/module.cc
index d6cc39a..463b2dd 100644
--- a/src/ast/module.cc
+++ b/src/ast/module.cc
@@ -16,6 +16,7 @@
 
 #include <utility>
 
+#include "src/ast/named_type.h"
 #include "src/program_builder.h"
 
 TINT_INSTANTIATE_TYPEINFO(tint::ast::Module);
@@ -50,6 +51,17 @@
 
 Module::~Module() = default;
 
+const ast::NamedType* Module::LookupType(Symbol name) const {
+  for (auto ct : ConstructedTypes()) {
+    if (auto* ty = ct.ast->As<ast::NamedType>()) {
+      if (ty->name() == name) {
+        return ty;
+      }
+    }
+  }
+  return nullptr;
+}
+
 Module* Module::Clone(CloneContext* ctx) const {
   auto* out = ctx->dst->create<Module>();
   out->Copy(ctx, this);
@@ -80,7 +92,7 @@
   make_indent(out, indent);
   out << "Module{" << std::endl;
   indent += 2;
-  for (auto* const ty : constructed_types_) {
+  for (auto const ty : constructed_types_) {
     make_indent(out, indent);
     if (auto* alias = ty->As<sem::Alias>()) {
       out << alias->symbol().to_str() << " -> " << alias->type()->type_name()
diff --git a/src/ast/module.h b/src/ast/module.h
index fe319bc..2b6b4dd 100644
--- a/src/ast/module.h
+++ b/src/ast/module.h
@@ -19,10 +19,13 @@
 #include <vector>
 
 #include "src/ast/function.h"
+#include "src/ast/type.h"
 
 namespace tint {
 namespace ast {
 
+class NamedType;
+
 /// Module holds the top-level AST types, functions and global variables used by
 /// a Program.
 class Module : public Castable<Module, Node> {
@@ -58,6 +61,17 @@
     global_declarations_.push_back(var);
   }
 
+  /// @returns true if the module has the global declaration `decl`
+  /// @param decl the declaration to check
+  bool HasGlobalDeclaration(const Cloneable* decl) const {
+    for (auto* d : global_declarations_) {
+      if (d == decl) {
+        return true;
+      }
+    }
+    return false;
+  }
+
   /// @returns the global variables for the translation unit
   const VariableList& GlobalVariables() const { return global_variables_; }
 
@@ -67,14 +81,18 @@
   /// Adds a constructed type to the Builder.
   /// The type must be an alias or a struct.
   /// @param type the constructed type to add
-  void AddConstructedType(sem::Type* type) {
+  void AddConstructedType(typ::Type type) {
     TINT_ASSERT(type);
     constructed_types_.push_back(type);
-    global_declarations_.push_back(type);
+    global_declarations_.push_back(const_cast<sem::Type*>(type.sem));
   }
 
+  /// @returns the NamedType registered as a ConstructedType()
+  /// @param name the name of the type to search for
+  const ast::NamedType* LookupType(Symbol name) const;
+
   /// @returns the constructed types in the translation unit
-  const std::vector<sem::Type*>& ConstructedTypes() const {
+  const std::vector<typ::Type>& ConstructedTypes() const {
     return constructed_types_;
   }
 
@@ -115,7 +133,7 @@
 
  private:
   std::vector<Cloneable*> global_declarations_;
-  std::vector<sem::Type*> constructed_types_;
+  std::vector<typ::Type> constructed_types_;
   FunctionList functions_;
   VariableList global_variables_;
 };
diff --git a/src/reader/wgsl/parser_impl_global_decl_test.cc b/src/reader/wgsl/parser_impl_global_decl_test.cc
index 79fddcb..72a0d49 100644
--- a/src/reader/wgsl/parser_impl_global_decl_test.cc
+++ b/src/reader/wgsl/parser_impl_global_decl_test.cc
@@ -163,7 +163,7 @@
   auto program = p->program();
   ASSERT_EQ(program.AST().ConstructedTypes().size(), 1u);
 
-  auto* t = program.AST().ConstructedTypes()[0];
+  auto t = program.AST().ConstructedTypes()[0];
   ASSERT_NE(t, nullptr);
   ASSERT_TRUE(t->Is<sem::StructType>());
 
@@ -181,7 +181,7 @@
   auto program = p->program();
   ASSERT_EQ(program.AST().ConstructedTypes().size(), 1u);
 
-  auto* t = program.AST().ConstructedTypes()[0];
+  auto t = program.AST().ConstructedTypes()[0];
   ASSERT_NE(t, nullptr);
   ASSERT_TRUE(t->Is<sem::StructType>());
 
@@ -208,7 +208,7 @@
   auto program = p->program();
   ASSERT_EQ(program.AST().ConstructedTypes().size(), 1u);
 
-  auto* t = program.AST().ConstructedTypes()[0];
+  auto t = program.AST().ConstructedTypes()[0];
   ASSERT_NE(t, nullptr);
   ASSERT_TRUE(t->Is<sem::StructType>());
 
diff --git a/src/transform/canonicalize_entry_point_io.cc b/src/transform/canonicalize_entry_point_io.cc
index d31b2d0..ab09015 100644
--- a/src/transform/canonicalize_entry_point_io.cc
+++ b/src/transform/canonicalize_entry_point_io.cc
@@ -65,7 +65,7 @@
 
   // Strip entry point IO decorations from struct declarations.
   // TODO(jrprice): This code is duplicated with the SPIR-V transform.
-  for (auto* ty : ctx.src->AST().ConstructedTypes()) {
+  for (auto ty : ctx.src->AST().ConstructedTypes()) {
     if (auto* struct_ty = ty->As<sem::StructType>()) {
       // Build new list of struct members without entry point IO decorations.
       ast::StructMemberList new_struct_members;
diff --git a/src/transform/spirv.cc b/src/transform/spirv.cc
index 47b8aa6..29c099e 100644
--- a/src/transform/spirv.cc
+++ b/src/transform/spirv.cc
@@ -110,7 +110,7 @@
   // ```
 
   // Strip entry point IO decorations from struct declarations.
-  for (auto* ty : ctx.src->AST().ConstructedTypes()) {
+  for (auto ty : ctx.src->AST().ConstructedTypes()) {
     if (auto* struct_ty = ty->As<sem::StructType>()) {
       // Build new list of struct members without entry point IO decorations.
       ast::StructMemberList new_struct_members;
diff --git a/src/writer/hlsl/generator_impl.cc b/src/writer/hlsl/generator_impl.cc
index e4ed9fd..defa30f 100644
--- a/src/writer/hlsl/generator_impl.cc
+++ b/src/writer/hlsl/generator_impl.cc
@@ -119,7 +119,7 @@
     register_global(global);
   }
 
-  for (auto* const ty : builder_.AST().ConstructedTypes()) {
+  for (auto const ty : builder_.AST().ConstructedTypes()) {
     if (!EmitConstructedType(out, ty)) {
       return false;
     }
diff --git a/src/writer/msl/generator_impl.cc b/src/writer/msl/generator_impl.cc
index 1c239a7..f3170bc 100644
--- a/src/writer/msl/generator_impl.cc
+++ b/src/writer/msl/generator_impl.cc
@@ -86,7 +86,7 @@
     global_variables_.set(global->symbol(), sem);
   }
 
-  for (auto* const ty : program_->AST().ConstructedTypes()) {
+  for (auto const ty : program_->AST().ConstructedTypes()) {
     if (!EmitConstructedType(ty)) {
       return false;
     }