ast: Replace NamedType with TypeDecl

TypeDecls (alias, structure) are not a types - they declare types.
ast::TypeName is what's used for a ast::Type.

Previously we were trying to automatically convert these to TypeNames in the builder, but having these inherit from ast::Type was extremely error prone.

reader/spirv was actually constructing ast::Structs and using them as types, which is invalid.

Change-Id: I05773ad6d488626606019015b84217a5a55a8e8a
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/53802
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
diff --git a/src/ast/alias.h b/src/ast/alias.h
index dc2dd8b..6e3dd8d 100644
--- a/src/ast/alias.h
+++ b/src/ast/alias.h
@@ -17,13 +17,13 @@
 
 #include <string>
 
-#include "src/ast/named_type.h"
+#include "src/ast/type_decl.h"
 
 namespace tint {
 namespace ast {
 
 /// A type alias type. Holds a name and pointer to another type.
-class Alias : public Castable<Alias, NamedType> {
+class Alias : public Castable<Alias, TypeDecl> {
  public:
   /// Constructor
   /// @param program_id the identifier of the program that owns this node
diff --git a/src/ast/alias_test.cc b/src/ast/alias_test.cc
index e55428d..8ae7a63 100644
--- a/src/ast/alias_test.cc
+++ b/src/ast/alias_test.cc
@@ -46,7 +46,7 @@
 TEST_F(AstAliasTest, TypeName_LinearTime) {
   Type* type = ty.i32();
   for (int i = 0; i < 1024; i++) {
-    type = Alias(Symbols().New(), type);
+    type = ty.Of(Alias(Symbols().New(), type));
   }
   for (int i = 0; i < 16384; i++) {
     type->type_name();
@@ -58,24 +58,6 @@
   EXPECT_EQ(at->type_name(), "__alias_$1__i32");
 }
 
-TEST_F(AstAliasTest, FriendlyName) {
-  auto* at = Alias("Particle", create<I32>());
-  EXPECT_EQ(at->FriendlyName(Symbols()), "Particle");
-}
-
-TEST_F(AstAliasTest, UnwrapAll_TwiceAliasPointerTwiceAlias) {
-  auto* u32 = create<U32>();
-  auto* a = create<ast::Alias>(Sym("a_type"), u32);
-  auto* aa = create<ast::Alias>(Sym("aa_type"), a);
-  auto* paa = create<Pointer>(aa, StorageClass::kUniform, Access::kUndefined);
-  auto* apaa = create<ast::Alias>(Sym("paa_type"), paa);
-  auto* aapaa = create<ast::Alias>(Sym("aapaa_type"), apaa);
-
-  EXPECT_EQ(aapaa->symbol(), Symbol(4, ID()));
-  EXPECT_EQ(aapaa->type(), apaa);
-  EXPECT_EQ(aapaa->UnwrapAll(), u32);
-}
-
 }  // namespace
 }  // namespace ast
 }  // namespace tint
diff --git a/src/ast/ast_type.cc b/src/ast/ast_type.cc
index 6702bd9..6dbf38b 100644
--- a/src/ast/ast_type.cc
+++ b/src/ast/ast_type.cc
@@ -40,9 +40,7 @@
 Type* Type::UnwrapAll() {
   auto* type = this;
   while (true) {
-    if (auto* alias = type->As<Alias>()) {
-      type = alias->type();
-    } else if (auto* ptr = type->As<Pointer>()) {
+    if (auto* ptr = type->As<Pointer>()) {
       type = ptr->type();
     } else {
       break;
diff --git a/src/ast/module.cc b/src/ast/module.cc
index 2de195f..fcb7216 100644
--- a/src/ast/module.cc
+++ b/src/ast/module.cc
@@ -16,7 +16,7 @@
 
 #include <utility>
 
-#include "src/ast/named_type.h"
+#include "src/ast/type_decl.h"
 #include "src/program_builder.h"
 
 TINT_INSTANTIATE_TYPEINFO(tint::ast::Module);
@@ -36,7 +36,7 @@
       continue;
     }
 
-    if (auto* ty = decl->As<ast::NamedType>()) {
+    if (auto* ty = decl->As<ast::TypeDecl>()) {
       constructed_types_.push_back(ty);
     } else if (auto* func = decl->As<Function>()) {
       functions_.push_back(func);
@@ -51,7 +51,7 @@
 
 Module::~Module() = default;
 
-const ast::NamedType* Module::LookupType(Symbol name) const {
+const ast::TypeDecl* Module::LookupType(Symbol name) const {
   for (auto* ty : ConstructedTypes()) {
     if (ty->name() == name) {
       return ty;
@@ -67,7 +67,7 @@
   global_declarations_.push_back(var);
 }
 
-void Module::AddConstructedType(ast::NamedType* type) {
+void Module::AddConstructedType(ast::TypeDecl* type) {
   TINT_ASSERT(type);
   constructed_types_.push_back(type);
   global_declarations_.push_back(type);
@@ -92,7 +92,7 @@
       TINT_ICE(ctx->dst->Diagnostics()) << "src global declaration was nullptr";
       continue;
     }
-    if (auto* ty = decl->As<ast::NamedType>()) {
+    if (auto* ty = decl->As<ast::TypeDecl>()) {
       AddConstructedType(ty);
     } else if (auto* func = decl->As<Function>()) {
       AddFunction(func);
@@ -115,9 +115,6 @@
     if (auto* alias = ty->As<ast::Alias>()) {
       out << alias->symbol().to_str() << " -> " << alias->type()->type_name()
           << std::endl;
-      if (auto* str = alias->type()->As<ast::Struct>()) {
-        str->to_str(sem, out, indent);
-      }
     } else if (auto* str = ty->As<ast::Struct>()) {
       str->to_str(sem, out, indent);
     }
diff --git a/src/ast/module.h b/src/ast/module.h
index 2ea6219..af502cf 100644
--- a/src/ast/module.h
+++ b/src/ast/module.h
@@ -24,7 +24,7 @@
 namespace tint {
 namespace ast {
 
-class NamedType;
+class TypeDecl;
 
 /// Module holds the top-level AST types, functions and global variables used by
 /// a Program.
@@ -73,16 +73,16 @@
   /// @returns the global variables for the translation unit
   VariableList& GlobalVariables() { return global_variables_; }
 
-  /// Adds a constructed type to the Builder.
-  /// @param type the constructed type to add
-  void AddConstructedType(ast::NamedType* type);
+  /// Adds a type declaration to the Builder.
+  /// @param decl the constructed type declaration to add
+  void AddConstructedType(ast::TypeDecl* decl);
 
-  /// @returns the NamedType registered as a ConstructedType()
+  /// @returns the TypeDecl registered as a ConstructedType()
   /// @param name the name of the type to search for
-  const ast::NamedType* LookupType(Symbol name) const;
+  const ast::TypeDecl* LookupType(Symbol name) const;
 
   /// @returns the constructed types in the translation unit
-  const std::vector<ast::NamedType*>& ConstructedTypes() const {
+  const std::vector<ast::TypeDecl*>& ConstructedTypes() const {
     return constructed_types_;
   }
 
@@ -118,7 +118,7 @@
 
  private:
   std::vector<ast::Node*> global_declarations_;
-  std::vector<ast::NamedType*> constructed_types_;
+  std::vector<ast::TypeDecl*> constructed_types_;
   FunctionList functions_;
   VariableList global_variables_;
 };
diff --git a/src/ast/named_type.h b/src/ast/named_type.h
deleted file mode 100644
index c0c157b..0000000
--- a/src/ast/named_type.h
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2021 The Tint Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef SRC_AST_NAMED_TYPE_H_
-#define SRC_AST_NAMED_TYPE_H_
-
-#include <string>
-
-#include "src/ast/type.h"
-
-namespace tint {
-namespace ast {
-
-/// The base class for user declared, named types.
-class NamedType : public Castable<NamedType, Type> {
- public:
-  /// Create a new struct statement
-  /// @param program_id the identifier of the program that owns this node
-  /// @param source The input source for the import statement
-  /// @param name The name of the structure
-  NamedType(ProgramID program_id, const Source& source, Symbol name);
-  /// Move constructor
-  NamedType(NamedType&&);
-
-  ~NamedType() override;
-
-  /// @returns the name of the structure
-  Symbol name() const { return name_; }
-
-  /// @param symbols the program's symbol table
-  /// @returns the name for this type that closely resembles how it would be
-  /// declared in WGSL.
-  std::string FriendlyName(const SymbolTable& symbols) const override;
-
- private:
-  NamedType(const NamedType&) = delete;
-  NamedType& operator=(const NamedType&) = delete;
-
-  Symbol const name_;
-};
-
-}  // namespace ast
-}  // namespace tint
-
-#endif  // SRC_AST_NAMED_TYPE_H_
diff --git a/src/ast/struct.h b/src/ast/struct.h
index d9fe744..48a7e7e 100644
--- a/src/ast/struct.h
+++ b/src/ast/struct.h
@@ -19,14 +19,14 @@
 #include <utility>
 
 #include "src/ast/decoration.h"
-#include "src/ast/named_type.h"
 #include "src/ast/struct_member.h"
+#include "src/ast/type_decl.h"
 
 namespace tint {
 namespace ast {
 
 /// A struct statement.
-class Struct : public Castable<Struct, NamedType> {
+class Struct : public Castable<Struct, TypeDecl> {
  public:
   /// Create a new struct statement
   /// @param program_id the identifier of the program that owns this node
diff --git a/src/ast/struct_test.cc b/src/ast/struct_test.cc
index 3e37625..1404ce8 100644
--- a/src/ast/struct_test.cc
+++ b/src/ast/struct_test.cc
@@ -144,13 +144,6 @@
   EXPECT_EQ(s->type_name(), "__struct_$1");
 }
 
-TEST_F(AstStructTest, FriendlyName) {
-  auto name = Sym("my_struct");
-  auto* s =
-      create<ast::Struct>(name, ast::StructMemberList{}, ast::DecorationList{});
-  EXPECT_EQ(s->FriendlyName(Symbols()), "my_struct");
-}
-
 }  // namespace
 }  // namespace ast
 }  // namespace tint
diff --git a/src/ast/named_type.cc b/src/ast/type_decl.cc
similarity index 66%
rename from src/ast/named_type.cc
rename to src/ast/type_decl.cc
index 52d7125..4337d39 100644
--- a/src/ast/named_type.cc
+++ b/src/ast/type_decl.cc
@@ -12,26 +12,29 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/ast/named_type.h"
+#include "src/ast/type_decl.h"
 
 #include "src/program_builder.h"
 
-TINT_INSTANTIATE_TYPEINFO(tint::ast::NamedType);
+TINT_INSTANTIATE_TYPEINFO(tint::ast::TypeDecl);
 
 namespace tint {
 namespace ast {
 
-NamedType::NamedType(ProgramID program_id, const Source& source, Symbol name)
+TypeDecl::TypeDecl(ProgramID program_id, const Source& source, Symbol name)
     : Base(program_id, source), name_(name) {
   TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(name, program_id);
 }
 
-NamedType::NamedType(NamedType&&) = default;
+TypeDecl::TypeDecl(TypeDecl&&) = default;
 
-NamedType::~NamedType() = default;
+TypeDecl::~TypeDecl() = default;
 
-std::string NamedType::FriendlyName(const SymbolTable& symbols) const {
-  return symbols.NameFor(name());
+void TypeDecl::to_str(const sem::Info&,
+                      std::ostream& out,
+                      size_t indent) const {
+  make_indent(out, indent);
+  out << type_name();
 }
 
 }  // namespace ast
diff --git a/src/ast/type_decl.h b/src/ast/type_decl.h
new file mode 100644
index 0000000..c942b0c
--- /dev/null
+++ b/src/ast/type_decl.h
@@ -0,0 +1,62 @@
+// Copyright 2021 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef SRC_AST_TYPE_DECL_H_
+#define SRC_AST_TYPE_DECL_H_
+
+#include <string>
+
+#include "src/ast/type.h"
+
+namespace tint {
+namespace ast {
+
+/// The base class for type declarations.
+class TypeDecl : public Castable<TypeDecl, Node> {
+ public:
+  /// Create a new struct statement
+  /// @param program_id the identifier of the program that owns this node
+  /// @param source The input source for the import statement
+  /// @param name The name of the structure
+  TypeDecl(ProgramID program_id, const Source& source, Symbol name);
+  /// Move constructor
+  TypeDecl(TypeDecl&&);
+
+  ~TypeDecl() override;
+
+  /// @returns the name of the type declaration
+  Symbol name() const { return name_; }
+
+  /// Writes a representation of the node to the output stream
+  /// @param sem the semantic info for the program
+  /// @param out the stream to write to
+  /// @param indent number of spaces to indent the node when writing
+  void to_str(const sem::Info& sem,
+              std::ostream& out,
+              size_t indent) const override;
+
+  /// @returns the name for this type. The type name is unique over all types.
+  virtual std::string type_name() const = 0;
+
+ private:
+  TypeDecl(const TypeDecl&) = delete;
+  TypeDecl& operator=(const TypeDecl&) = delete;
+
+  Symbol const name_;
+};
+
+}  // namespace ast
+}  // namespace tint
+
+#endif  // SRC_AST_TYPE_DECL_H_