Add semantic::Node

Rename Program(Builder)::Nodes to ASTNodes, and add SemNodes.

Bug: tint:390
Change-Id: If501ea5f5d1cbb4bc2673b303aa8ebce7195e2c3
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/39005
Commit-Queue: Ben Clayton <bclayton@google.com>
Reviewed-by: dan sinclair <dsinclair@chromium.org>
diff --git a/BUILD.gn b/BUILD.gn
index a49c65c..dc730a9 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -379,6 +379,7 @@
     "src/reader/reader.h",
     "src/scope_stack.h",
     "src/semantic/info.h",
+    "src/semantic/node.h",
     "src/semantic/sem_info.cc",
     "src/source.cc",
     "src/source.h",
diff --git a/fuzzers/tint_ast_clone_fuzzer.cc b/fuzzers/tint_ast_clone_fuzzer.cc
index 0a2774a..64100bf 100644
--- a/fuzzers/tint_ast_clone_fuzzer.cc
+++ b/fuzzers/tint_ast_clone_fuzzer.cc
@@ -65,14 +65,14 @@
 
   // Check that none of the AST nodes or type pointers in dst are found in src
   std::unordered_set<tint::ast::Node*> src_nodes;
-  for (auto* src_node : src.Nodes().Objects()) {
+  for (auto* src_node : src.ASTNodes().Objects()) {
     src_nodes.emplace(src_node);
   }
   std::unordered_set<tint::type::Type*> src_types;
   for (auto* src_type : src.Types()) {
     src_types.emplace(src_type);
   }
-  for (auto* dst_node : dst.Nodes().Objects()) {
+  for (auto* dst_node : dst.ASTNodes().Objects()) {
     ASSERT_EQ(src_nodes.count(dst_node), 0u);
   }
   for (auto* dst_type : dst.Types()) {
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 0f34ad9..ba9685f 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -193,6 +193,7 @@
   reader/reader.h
   scope_stack.h
   semantic/info.h
+  semantic/node.h
   semantic/sem_info.cc
   source.cc
   source.h
diff --git a/src/ast/module_clone_test.cc b/src/ast/module_clone_test.cc
index e38c937..dad6d56 100644
--- a/src/ast/module_clone_test.cc
+++ b/src/ast/module_clone_test.cc
@@ -124,14 +124,14 @@
 
   // Check that none of the AST nodes or type pointers in dst are found in src
   std::unordered_set<ast::Node*> src_nodes;
-  for (auto* src_node : src.Nodes().Objects()) {
+  for (auto* src_node : src.ASTNodes().Objects()) {
     src_nodes.emplace(src_node);
   }
   std::unordered_set<type::Type*> src_types;
   for (auto* src_type : src.Types()) {
     src_types.emplace(src_type);
   }
-  for (auto* dst_node : dst.Nodes().Objects()) {
+  for (auto* dst_node : dst.ASTNodes().Objects()) {
     ASSERT_EQ(src_nodes.count(dst_node), 0u) << dst.str(dst_node);
   }
   for (auto* dst_type : dst.Types()) {
diff --git a/src/program.cc b/src/program.cc
index 36df9fd..d5ff433 100644
--- a/src/program.cc
+++ b/src/program.cc
@@ -29,7 +29,8 @@
 
 Program::Program(Program&& program)
     : types_(std::move(program.types_)),
-      nodes_(std::move(program.nodes_)),
+      ast_nodes_(std::move(program.ast_nodes_)),
+      sem_nodes_(std::move(program.sem_nodes_)),
       ast_(std::move(program.ast_)),
       sem_(std::move(program.sem_)),
       symbols_(std::move(program.symbols_)),
@@ -51,10 +52,11 @@
   // The above must be called *before* the calls to std::move() below
 
   types_ = std::move(builder.Types());
-  nodes_ = std::move(builder.Nodes());
-  ast_ = nodes_.Create<ast::Module>(Source{}, builder.AST().ConstructedTypes(),
-                                    builder.AST().Functions(),
-                                    builder.AST().GlobalVariables());
+  ast_nodes_ = std::move(builder.ASTNodes());
+  sem_nodes_ = std::move(builder.SemNodes());
+  ast_ = ast_nodes_.Create<ast::Module>(
+      Source{}, builder.AST().ConstructedTypes(), builder.AST().Functions(),
+      builder.AST().GlobalVariables());
   sem_ = std::move(builder.Sem());
   symbols_ = std::move(builder.Symbols());
   diagnostics_ = std::move(builder.Diagnostics());
@@ -74,7 +76,8 @@
   program.AssertNotMoved();
   program.moved_ = true;
   types_ = std::move(program.types_);
-  nodes_ = std::move(program.nodes_);
+  ast_nodes_ = std::move(program.ast_nodes_);
+  sem_nodes_ = std::move(program.sem_nodes_);
   ast_ = std::move(program.ast_);
   sem_ = std::move(program.sem_);
   symbols_ = std::move(program.symbols_);
diff --git a/src/program.h b/src/program.h
index 224db0f..7388693 100644
--- a/src/program.h
+++ b/src/program.h
@@ -20,6 +20,7 @@
 #include "src/ast/function.h"
 #include "src/diagnostic/diagnostic.h"
 #include "src/semantic/info.h"
+#include "src/semantic/node.h"
 #include "src/symbol_table.h"
 #include "src/type/type_manager.h"
 
@@ -37,8 +38,11 @@
 /// Program holds the AST, Type information and SymbolTable for a tint program.
 class Program {
  public:
-  /// ASTNodes is an alias to BlockAllocator<ast::Node>
-  using ASTNodes = BlockAllocator<ast::Node>;
+  /// ASTNodeAllocator is an alias to BlockAllocator<ast::Node>
+  using ASTNodeAllocator = BlockAllocator<ast::Node>;
+
+  /// SemNodeAllocator is an alias to BlockAllocator<semantic::Node>
+  using SemNodeAllocator = BlockAllocator<semantic::Node>;
 
   /// Constructor
   Program();
@@ -66,9 +70,15 @@
   }
 
   /// @returns a reference to the program's AST nodes storage
-  const ASTNodes& Nodes() const {
+  const ASTNodeAllocator& ASTNodes() const {
     AssertNotMoved();
-    return nodes_;
+    return ast_nodes_;
+  }
+
+  /// @returns a reference to the program's semantic nodes storage
+  const SemNodeAllocator& SemNodes() const {
+    AssertNotMoved();
+    return sem_nodes_;
   }
 
   /// @returns a reference to the program's AST root Module
@@ -134,7 +144,8 @@
   void AssertNotMoved() const;
 
   type::Manager types_;
-  ASTNodes nodes_;
+  ASTNodeAllocator ast_nodes_;
+  SemNodeAllocator sem_nodes_;
   ast::Module* ast_;
   semantic::Info sem_;
   SymbolTable symbols_;
diff --git a/src/program_builder.cc b/src/program_builder.cc
index 146d644..ddd146a 100644
--- a/src/program_builder.cc
+++ b/src/program_builder.cc
@@ -25,12 +25,13 @@
 namespace tint {
 
 ProgramBuilder::ProgramBuilder()
-    : ty(this), ast_(nodes_.Create<ast::Module>(Source{})) {}
+    : ty(this), ast_(ast_nodes_.Create<ast::Module>(Source{})) {}
 
 ProgramBuilder::ProgramBuilder(ProgramBuilder&& rhs)
     : ty(std::move(rhs.ty)),
       types_(std::move(rhs.types_)),
-      nodes_(std::move(rhs.nodes_)),
+      ast_nodes_(std::move(rhs.ast_nodes_)),
+      sem_nodes_(std::move(rhs.sem_nodes_)),
       ast_(rhs.ast_),
       sem_(std::move(rhs.sem_)),
       symbols_(std::move(rhs.symbols_)) {
@@ -44,7 +45,8 @@
   AssertNotMoved();
   ty = std::move(rhs.ty);
   types_ = std::move(rhs.types_);
-  nodes_ = std::move(rhs.nodes_);
+  ast_nodes_ = std::move(rhs.ast_nodes_);
+  sem_nodes_ = std::move(rhs.sem_nodes_);
   ast_ = rhs.ast_;
   sem_ = std::move(rhs.sem_);
   symbols_ = std::move(rhs.symbols_);
diff --git a/src/program_builder.h b/src/program_builder.h
index 5355e1e..2fd6377 100644
--- a/src/program_builder.h
+++ b/src/program_builder.h
@@ -38,6 +38,7 @@
 #include "src/diagnostic/diagnostic.h"
 #include "src/program.h"
 #include "src/semantic/info.h"
+#include "src/semantic/node.h"
 #include "src/symbol_table.h"
 #include "src/type/alias_type.h"
 #include "src/type/array_type.h"
@@ -61,8 +62,11 @@
 /// Program.
 class ProgramBuilder {
  public:
-  /// ASTNodes is an alias to BlockAllocator<ast::Node>
-  using ASTNodes = BlockAllocator<ast::Node>;
+  /// ASTNodeAllocator is an alias to BlockAllocator<ast::Node>
+  using ASTNodeAllocator = BlockAllocator<ast::Node>;
+
+  /// SemNodeAllocator is an alias to BlockAllocator<semantic::Node>
+  using SemNodeAllocator = BlockAllocator<semantic::Node>;
 
   /// `i32` is a type alias to `int`.
   /// Useful for passing to template methods such as `vec2<i32>()` to imitate
@@ -121,15 +125,27 @@
   }
 
   /// @returns a reference to the program's AST nodes storage
-  ASTNodes& Nodes() {
+  ASTNodeAllocator& ASTNodes() {
     AssertNotMoved();
-    return nodes_;
+    return ast_nodes_;
   }
 
   /// @returns a reference to the program's AST nodes storage
-  const ASTNodes& Nodes() const {
+  const ASTNodeAllocator& ASTNodes() const {
     AssertNotMoved();
-    return nodes_;
+    return ast_nodes_;
+  }
+
+  /// @returns a reference to the program's semantic nodes storage
+  SemNodeAllocator& SemNodes() {
+    AssertNotMoved();
+    return sem_nodes_;
+  }
+
+  /// @returns a reference to the program's semantic nodes storage
+  const SemNodeAllocator& SemNodes() const {
+    AssertNotMoved();
+    return sem_nodes_;
   }
 
   /// @returns a reference to the program's AST root Module
@@ -207,8 +223,8 @@
   /// @returns a string representation of the node
   std::string str(const ast::Node* node) const;
 
-  /// creates a new ast::Node owned by the Module. When the Module is
-  /// destructed, the ast::Node will also be destructed.
+  /// Creates a new ast::Node owned by the ProgramBuilder. When the
+  /// ProgramBuilder is destructed, the ast::Node will also be destructed.
   /// @param source the Source of the node
   /// @param args the arguments to pass to the type constructor
   /// @returns the node pointer
@@ -216,24 +232,26 @@
   traits::EnableIfIsType<T, ast::Node>* create(const Source& source,
                                                ARGS&&... args) {
     AssertNotMoved();
-    return nodes_.Create<T>(source, std::forward<ARGS>(args)...);
+    return ast_nodes_.Create<T>(source, std::forward<ARGS>(args)...);
   }
 
-  /// creates a new ast::Node owned by the Module, injecting the current Source
-  /// as set by the last call to SetSource() as the only argument to the
+  /// Creates a new ast::Node owned by the ProgramBuilder, injecting the current
+  /// Source as set by the last call to SetSource() as the only argument to the
   /// constructor.
-  /// When the Module is destructed, the ast::Node will also be destructed.
+  /// When the ProgramBuilder is destructed, the ast::Node will also be
+  /// destructed.
   /// @returns the node pointer
   template <typename T>
   traits::EnableIfIsType<T, ast::Node>* create() {
     AssertNotMoved();
-    return nodes_.Create<T>(source_);
+    return ast_nodes_.Create<T>(source_);
   }
 
-  /// creates a new ast::Node owned by the Module, injecting the current Source
-  /// as set by the last call to SetSource() as the first argument to the
+  /// Creates a new ast::Node owned by the ProgramBuilder, injecting the current
+  /// Source as set by the last call to SetSource() as the first argument to the
   /// constructor.
-  /// When the Module is destructed, the ast::Node will also be destructed.
+  /// When the ProgramBuilder is destructed, the ast::Node will also be
+  /// destructed.
   /// @param arg0 the first arguments to pass to the type constructor
   /// @param args the remaining arguments to pass to the type constructor
   /// @returns the node pointer
@@ -244,13 +262,24 @@
                    T>*
   create(ARG0&& arg0, ARGS&&... args) {
     AssertNotMoved();
-    return nodes_.Create<T>(source_, std::forward<ARG0>(arg0),
-                            std::forward<ARGS>(args)...);
+    return ast_nodes_.Create<T>(source_, std::forward<ARG0>(arg0),
+                                std::forward<ARGS>(args)...);
   }
 
-  /// creates a new type::Type owned by the Module.
-  /// When the Module is destructed, owned Module and the returned
-  /// `Type` will also be destructed.
+  /// Creates a new semantic::Node owned by the ProgramBuilder.
+  /// When the ProgramBuilder is destructed, the semantic::Node will also be
+  /// destructed.
+  /// @param args the arguments to pass to the type constructor
+  /// @returns the node pointer
+  template <typename T, typename... ARGS>
+  traits::EnableIfIsType<T, semantic::Node>* create(ARGS&&... args) {
+    AssertNotMoved();
+    return sem_nodes_.Create<T>(std::forward<ARGS>(args)...);
+  }
+
+  /// Creates a new type::Type owned by the ProgramBuilder.
+  /// When the ProgramBuilder is destructed, owned ProgramBuilder and the
+  /// returned`Type` will also be destructed.
   /// Types are unique (de-aliased), and so calling create() for the same `T`
   /// and arguments will return the same pointer.
   /// @warning Use this method to acquire a type only if all of its type
@@ -920,7 +949,8 @@
 
  private:
   type::Manager types_;
-  ASTNodes nodes_;
+  ASTNodeAllocator ast_nodes_;
+  SemNodeAllocator sem_nodes_;
   ast::Module* ast_;
   semantic::Info sem_;
   SymbolTable symbols_;
diff --git a/src/semantic/node.h b/src/semantic/node.h
new file mode 100644
index 0000000..587fbe7
--- /dev/null
+++ b/src/semantic/node.h
@@ -0,0 +1,33 @@
+// 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_SEMANTIC_NODE_H_
+#define SRC_SEMANTIC_NODE_H_
+
+#include "src/castable.h"
+
+namespace tint {
+namespace semantic {
+
+/// Node is the base class for all semantic nodes
+class Node : public Castable<Node> {
+ public:
+  /// Destructor
+  ~Node() override;
+};
+
+}  // namespace semantic
+}  // namespace tint
+
+#endif  // SRC_SEMANTIC_NODE_H_