[ir] Remove ast pointers.

This CL removes the AST pointers from the IR nodes.

Bug: tint:1718
Change-Id: I818e1debc644b366c6e8378f448683b1b7d8fb00
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/116365
Reviewed-by: Ben Clayton <bclayton@google.com>
Commit-Queue: Dan Sinclair <dsinclair@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
diff --git a/src/tint/ir/binary_test.cc b/src/tint/ir/binary_test.cc
index f234879..68341ad 100644
--- a/src/tint/ir/binary_test.cc
+++ b/src/tint/ir/binary_test.cc
@@ -48,7 +48,7 @@
     EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
 
     std::stringstream str;
-    instr->ToString(str, program->Symbols());
+    instr->ToString(str, b.builder.ir.symbols);
     EXPECT_EQ(str.str(), "%42 (i32) = 4 & 2");
 }
 
@@ -75,7 +75,7 @@
     EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
 
     std::stringstream str;
-    instr->ToString(str, program->Symbols());
+    instr->ToString(str, b.builder.ir.symbols);
     EXPECT_EQ(str.str(), "%42 (i32) = 4 | 2");
 }
 
@@ -102,7 +102,7 @@
     EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
 
     std::stringstream str;
-    instr->ToString(str, program->Symbols());
+    instr->ToString(str, b.builder.ir.symbols);
     EXPECT_EQ(str.str(), "%42 (i32) = 4 ^ 2");
 }
 
@@ -129,7 +129,7 @@
     EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
 
     std::stringstream str;
-    instr->ToString(str, program->Symbols());
+    instr->ToString(str, b.builder.ir.symbols);
     EXPECT_EQ(str.str(), "%42 (bool) = 4 && 2");
 }
 
@@ -156,7 +156,7 @@
     EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
 
     std::stringstream str;
-    instr->ToString(str, program->Symbols());
+    instr->ToString(str, b.builder.ir.symbols);
     EXPECT_EQ(str.str(), "%42 (bool) = 4 || 2");
 }
 
@@ -183,7 +183,7 @@
     EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
 
     std::stringstream str;
-    instr->ToString(str, program->Symbols());
+    instr->ToString(str, b.builder.ir.symbols);
     EXPECT_EQ(str.str(), "%42 (bool) = 4 == 2");
 }
 
@@ -210,7 +210,7 @@
     EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
 
     std::stringstream str;
-    instr->ToString(str, program->Symbols());
+    instr->ToString(str, b.builder.ir.symbols);
     EXPECT_EQ(str.str(), "%42 (bool) = 4 != 2");
 }
 
@@ -237,7 +237,7 @@
     EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
 
     std::stringstream str;
-    instr->ToString(str, program->Symbols());
+    instr->ToString(str, b.builder.ir.symbols);
     EXPECT_EQ(str.str(), "%42 (bool) = 4 < 2");
 }
 
@@ -264,7 +264,7 @@
     EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
 
     std::stringstream str;
-    instr->ToString(str, program->Symbols());
+    instr->ToString(str, b.builder.ir.symbols);
     EXPECT_EQ(str.str(), "%42 (bool) = 4 > 2");
 }
 
@@ -291,7 +291,7 @@
     EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
 
     std::stringstream str;
-    instr->ToString(str, program->Symbols());
+    instr->ToString(str, b.builder.ir.symbols);
     EXPECT_EQ(str.str(), "%42 (bool) = 4 <= 2");
 }
 
@@ -318,7 +318,7 @@
     EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
 
     std::stringstream str;
-    instr->ToString(str, program->Symbols());
+    instr->ToString(str, b.builder.ir.symbols);
     EXPECT_EQ(str.str(), "%42 (bool) = 4 >= 2");
 }
 
@@ -345,7 +345,7 @@
     EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
 
     std::stringstream str;
-    instr->ToString(str, program->Symbols());
+    instr->ToString(str, b.builder.ir.symbols);
     EXPECT_EQ(str.str(), "%42 (i32) = 4 << 2");
 }
 
@@ -372,7 +372,7 @@
     EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
 
     std::stringstream str;
-    instr->ToString(str, program->Symbols());
+    instr->ToString(str, b.builder.ir.symbols);
     EXPECT_EQ(str.str(), "%42 (i32) = 4 >> 2");
 }
 
@@ -399,7 +399,7 @@
     EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
 
     std::stringstream str;
-    instr->ToString(str, program->Symbols());
+    instr->ToString(str, b.builder.ir.symbols);
     EXPECT_EQ(str.str(), "%42 (i32) = 4 + 2");
 }
 
@@ -426,7 +426,7 @@
     EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
 
     std::stringstream str;
-    instr->ToString(str, program->Symbols());
+    instr->ToString(str, b.builder.ir.symbols);
     EXPECT_EQ(str.str(), "%42 (i32) = 4 - 2");
 }
 
@@ -453,7 +453,7 @@
     EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
 
     std::stringstream str;
-    instr->ToString(str, program->Symbols());
+    instr->ToString(str, b.builder.ir.symbols);
     EXPECT_EQ(str.str(), "%42 (i32) = 4 * 2");
 }
 
@@ -480,7 +480,7 @@
     EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
 
     std::stringstream str;
-    instr->ToString(str, program->Symbols());
+    instr->ToString(str, b.builder.ir.symbols);
     EXPECT_EQ(str.str(), "%42 (i32) = 4 / 2");
 }
 
@@ -507,7 +507,7 @@
     EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
 
     std::stringstream str;
-    instr->ToString(str, program->Symbols());
+    instr->ToString(str, b.builder.ir.symbols);
     EXPECT_EQ(str.str(), "%42 (i32) = 4 % 2");
 }
 
diff --git a/src/tint/ir/bitcast_test.cc b/src/tint/ir/bitcast_test.cc
index 91c5c4b..a6924df 100644
--- a/src/tint/ir/bitcast_test.cc
+++ b/src/tint/ir/bitcast_test.cc
@@ -41,7 +41,7 @@
     EXPECT_EQ(4_i, val->As<constant::Scalar<i32>>()->ValueAs<i32>());
 
     std::stringstream str;
-    instr->ToString(str, program->Symbols());
+    instr->ToString(str, b.builder.ir.symbols);
     EXPECT_EQ(str.str(), "%42 (i32) = bitcast(4)");
 }
 
diff --git a/src/tint/ir/builder.cc b/src/tint/ir/builder.cc
index 6bf98ef..0f43e23 100644
--- a/src/tint/ir/builder.cc
+++ b/src/tint/ir/builder.cc
@@ -17,11 +17,10 @@
 #include <utility>
 
 #include "src/tint/ir/builder_impl.h"
-#include "src/tint/program.h"
 
 namespace tint::ir {
 
-Builder::Builder(const Program* prog) : ir(prog) {}
+Builder::Builder() {}
 
 Builder::Builder(Module&& mod) : ir(std::move(mod)) {}
 
@@ -35,8 +34,8 @@
     return ir.flow_nodes.Create<Terminator>();
 }
 
-Function* Builder::CreateFunction(const ast::Function* ast_func) {
-    auto* ir_func = ir.flow_nodes.Create<Function>(ast_func);
+Function* Builder::CreateFunction() {
+    auto* ir_func = ir.flow_nodes.Create<Function>();
     ir_func->start_target = CreateBlock();
     ir_func->end_target = CreateTerminator();
 
@@ -46,8 +45,8 @@
     return ir_func;
 }
 
-If* Builder::CreateIf(const ast::Statement* stmt) {
-    auto* ir_if = ir.flow_nodes.Create<If>(stmt);
+If* Builder::CreateIf() {
+    auto* ir_if = ir.flow_nodes.Create<If>();
     ir_if->true_target = CreateBlock();
     ir_if->false_target = CreateBlock();
     ir_if->merge_target = CreateBlock();
@@ -59,8 +58,8 @@
     return ir_if;
 }
 
-Loop* Builder::CreateLoop(const ast::Statement* stmt) {
-    auto* ir_loop = ir.flow_nodes.Create<Loop>(stmt);
+Loop* Builder::CreateLoop() {
+    auto* ir_loop = ir.flow_nodes.Create<Loop>();
     ir_loop->start_target = CreateBlock();
     ir_loop->continuing_target = CreateBlock();
     ir_loop->merge_target = CreateBlock();
@@ -71,8 +70,8 @@
     return ir_loop;
 }
 
-Switch* Builder::CreateSwitch(const ast::SwitchStatement* stmt) {
-    auto* ir_switch = ir.flow_nodes.Create<Switch>(stmt);
+Switch* Builder::CreateSwitch() {
+    auto* ir_switch = ir.flow_nodes.Create<Switch>();
     ir_switch->merge_target = CreateBlock();
     return ir_switch;
 }
diff --git a/src/tint/ir/builder.h b/src/tint/ir/builder.h
index e444996..f760b5c 100644
--- a/src/tint/ir/builder.h
+++ b/src/tint/ir/builder.h
@@ -35,19 +35,13 @@
 #include "src/tint/type/i32.h"
 #include "src/tint/type/u32.h"
 
-// Forward Declarations
-namespace tint {
-class Program;
-}  // namespace tint
-
 namespace tint::ir {
 
-/// Builds an ir::Module from a given Program
+/// Builds an ir::Module
 class Builder {
   public:
     /// Constructor
-    /// @param prog the program this ir is associated with
-    explicit Builder(const Program* prog);
+    Builder();
     /// Constructor
     /// @param mod the ir::Module to wrap with this builder
     explicit Builder(Module&& mod);
@@ -60,25 +54,21 @@
     /// @returns a new terminator flow node
     Terminator* CreateTerminator();
 
-    /// Creates a function flow node for the given ast::Function
-    /// @param func the ast::Function
+    /// Creates a function flow node
     /// @returns the flow node
-    Function* CreateFunction(const ast::Function* func);
+    Function* CreateFunction();
 
-    /// Creates an if flow node for the given ast::IfStatement or ast::BreakIfStatement
-    /// @param stmt the ast::IfStatement or ast::BreakIfStatement
+    /// Creates an if flow node
     /// @returns the flow node
-    If* CreateIf(const ast::Statement* stmt);
+    If* CreateIf();
 
-    /// Creates a loop flow node for the given ast loop, while or for statement
-    /// @param stmt the ast loop, while or for statement
+    /// Creates a loop flow node
     /// @returns the flow node
-    Loop* CreateLoop(const ast::Statement* stmt);
+    Loop* CreateLoop();
 
-    /// Creates a switch flow node for the given ast::SwitchStatement
-    /// @param stmt the ast::SwitchStatment
+    /// Creates a switch flow node
     /// @returns the flow node
-    Switch* CreateSwitch(const ast::SwitchStatement* stmt);
+    Switch* CreateSwitch();
 
     /// Creates a case flow node for the given case branch.
     /// @param s the switch to create the case into
diff --git a/src/tint/ir/builder_impl.cc b/src/tint/ir/builder_impl.cc
index ccbe0e9..cf7321d 100644
--- a/src/tint/ir/builder_impl.cc
+++ b/src/tint/ir/builder_impl.cc
@@ -85,7 +85,7 @@
 }  // namespace
 
 BuilderImpl::BuilderImpl(const Program* program)
-    : builder(program),
+    : program_(program),
       clone_ctx_{
           type::CloneContext{{&program->Symbols()}, {&builder.ir.symbols, &builder.ir.types}},
           {&builder.ir.constants}} {}
@@ -122,8 +122,12 @@
     return nullptr;
 }
 
+Symbol BuilderImpl::CloneSymbol(Symbol sym) const {
+    return clone_ctx_.type_ctx.dst.st->Register(clone_ctx_.type_ctx.src.st->NameFor(sym));
+}
+
 ResultType BuilderImpl::Build() {
-    auto* sem = builder.ir.program->Sem().Module();
+    auto* sem = program_->Sem().Module();
 
     for (auto* decl : sem->DependencyOrderedDeclarations()) {
         bool ok = tint::Switch(
@@ -158,7 +162,8 @@
     // The flow stack should have been emptied when the previous function finished building.
     TINT_ASSERT(IR, flow_stack.IsEmpty());
 
-    auto* ir_func = builder.CreateFunction(ast_func);
+    auto* ir_func = builder.CreateFunction();
+    ir_func->name = CloneSymbol(ast_func->symbol);
     current_function_ = ir_func;
     builder.ir.functions.Push(ir_func);
 
@@ -244,7 +249,7 @@
 }
 
 bool BuilderImpl::EmitIf(const ast::IfStatement* stmt) {
-    auto* if_node = builder.CreateIf(stmt);
+    auto* if_node = builder.CreateIf();
 
     // Emit the if condition into the end of the preceding block
     auto reg = EmitExpression(stmt->condition);
@@ -287,7 +292,7 @@
 }
 
 bool BuilderImpl::EmitLoop(const ast::LoopStatement* stmt) {
-    auto* loop_node = builder.CreateLoop(stmt);
+    auto* loop_node = builder.CreateLoop();
 
     BranchTo(loop_node);
 
@@ -325,7 +330,7 @@
 }
 
 bool BuilderImpl::EmitWhile(const ast::WhileStatement* stmt) {
-    auto* loop_node = builder.CreateLoop(stmt);
+    auto* loop_node = builder.CreateLoop();
     // Continue is always empty, just go back to the start
     builder.Branch(loop_node->continuing_target, loop_node->start_target);
 
@@ -345,7 +350,7 @@
         }
 
         // Create an `if (cond) {} else {break;}` control flow
-        auto* if_node = builder.CreateIf(nullptr);
+        auto* if_node = builder.CreateIf();
         builder.Branch(if_node->true_target, if_node->merge_target);
         builder.Branch(if_node->false_target, loop_node->merge_target);
         if_node->condition = reg.Get();
@@ -366,7 +371,7 @@
 }
 
 bool BuilderImpl::EmitForLoop(const ast::ForLoopStatement* stmt) {
-    auto* loop_node = builder.CreateLoop(stmt);
+    auto* loop_node = builder.CreateLoop();
     builder.Branch(loop_node->continuing_target, loop_node->start_target);
 
     if (stmt->initializer) {
@@ -393,7 +398,7 @@
             }
 
             // Create an `if (cond) {} else {break;}` control flow
-            auto* if_node = builder.CreateIf(nullptr);
+            auto* if_node = builder.CreateIf();
             builder.Branch(if_node->true_target, if_node->merge_target);
             builder.Branch(if_node->false_target, loop_node->merge_target);
             if_node->condition = reg.Get();
@@ -422,7 +427,7 @@
 }
 
 bool BuilderImpl::EmitSwitch(const ast::SwitchStatement* stmt) {
-    auto* switch_node = builder.CreateSwitch(stmt);
+    auto* switch_node = builder.CreateSwitch();
 
     // Emit the condition into the preceding block
     auto reg = EmitExpression(stmt->condition);
@@ -438,7 +443,7 @@
     {
         FlowStackScope scope(this, switch_node);
 
-        const auto* sem = builder.ir.program->Sem().Get(stmt);
+        const auto* sem = program_->Sem().Get(stmt);
         for (const auto* c : sem->Cases()) {
             utils::Vector<Switch::CaseSelector, 4> selectors;
             for (const auto* selector : c->Selectors()) {
@@ -504,7 +509,7 @@
 }
 
 bool BuilderImpl::EmitBreakIf(const ast::BreakIfStatement* stmt) {
-    auto* if_node = builder.CreateIf(stmt);
+    auto* if_node = builder.CreateIf();
 
     // Emit the break-if condition into the end of the preceding block
     auto reg = EmitExpression(stmt->condition);
@@ -584,7 +589,7 @@
         return utils::Failure;
     }
 
-    auto* sem = builder.ir.program->Sem().Get(expr);
+    auto* sem = program_->Sem().Get(expr);
     auto* ty = sem->Type()->Clone(clone_ctx_.type_ctx);
 
     Binary* instr = nullptr;
@@ -658,7 +663,7 @@
         return utils::Failure;
     }
 
-    auto* sem = builder.ir.program->Sem().Get(expr);
+    auto* sem = program_->Sem().Get(expr);
     auto* ty = sem->Type()->Clone(clone_ctx_.type_ctx);
     auto* instr = builder.Bitcast(ty, val.Get());
 
@@ -667,7 +672,7 @@
 }
 
 utils::Result<Value*> BuilderImpl::EmitLiteral(const ast::LiteralExpression* lit) {
-    auto* sem = builder.ir.program->Sem().Get(lit);
+    auto* sem = program_->Sem().Get(lit);
     if (!sem) {
         diagnostics_.add_error(
             tint::diag::System::IR,
diff --git a/src/tint/ir/builder_impl.h b/src/tint/ir/builder_impl.h
index 77f130e..8c81319 100644
--- a/src/tint/ir/builder_impl.h
+++ b/src/tint/ir/builder_impl.h
@@ -32,20 +32,26 @@
 class Program;
 }  // namespace tint
 namespace tint::ast {
+class Attribute;
 class BinaryExpression;
 class BitcastExpression;
 class BlockStatement;
 class BreakIfStatement;
 class BreakStatement;
 class ContinueStatement;
+class Expression;
 class ForLoopStatement;
 class Function;
 class IfStatement;
 class LoopStatement;
 class LiteralExpression;
+class Node;
 class ReturnStatement;
 class Statement;
+class SwitchStatement;
+class Type;
 class WhileStatement;
+class Variable;
 }  // namespace tint::ast
 namespace tint::ir {
 class Block;
@@ -201,6 +207,10 @@
 
     FlowNode* FindEnclosingControl(ControlFlags flags);
 
+    const Program* program_ = nullptr;
+
+    Symbol CloneSymbol(Symbol sym) const;
+
     diag::List diagnostics_;
 
     Function* current_function_ = nullptr;
diff --git a/src/tint/ir/constant_test.cc b/src/tint/ir/constant_test.cc
index 87eec65..c6fe2e4 100644
--- a/src/tint/ir/constant_test.cc
+++ b/src/tint/ir/constant_test.cc
@@ -32,7 +32,7 @@
     auto* c = b.builder.Constant(1.2_f);
     EXPECT_EQ(1.2_f, c->value->As<constant::Scalar<f32>>()->ValueAs<f32>());
 
-    c->ToString(str, program->Symbols());
+    c->ToString(str, b.builder.ir.symbols);
     EXPECT_EQ("1.2", str.str());
 
     EXPECT_TRUE(c->value->Is<constant::Scalar<f32>>());
@@ -50,7 +50,7 @@
     auto* c = b.builder.Constant(1.1_h);
     EXPECT_EQ(1.1_h, c->value->As<constant::Scalar<f16>>()->ValueAs<f16>());
 
-    c->ToString(str, program->Symbols());
+    c->ToString(str, b.builder.ir.symbols);
     EXPECT_EQ("1.09961", str.str());
 
     EXPECT_FALSE(c->value->Is<constant::Scalar<f32>>());
@@ -68,7 +68,7 @@
     auto* c = b.builder.Constant(1_i);
     EXPECT_EQ(1_i, c->value->As<constant::Scalar<i32>>()->ValueAs<i32>());
 
-    c->ToString(str, program->Symbols());
+    c->ToString(str, b.builder.ir.symbols);
     EXPECT_EQ("1", str.str());
 
     EXPECT_FALSE(c->value->Is<constant::Scalar<f32>>());
@@ -86,7 +86,7 @@
     auto* c = b.builder.Constant(2_u);
     EXPECT_EQ(2_u, c->value->As<constant::Scalar<u32>>()->ValueAs<u32>());
 
-    c->ToString(str, program->Symbols());
+    c->ToString(str, b.builder.ir.symbols);
     EXPECT_EQ("2", str.str());
 
     EXPECT_FALSE(c->value->Is<constant::Scalar<f32>>());
@@ -104,14 +104,14 @@
     auto* c = b.builder.Constant(false);
     EXPECT_FALSE(c->value->As<constant::Scalar<bool>>()->ValueAs<bool>());
 
-    c->ToString(str, program->Symbols());
+    c->ToString(str, b.builder.ir.symbols);
     EXPECT_EQ("false", str.str());
 
     str.str("");
     c = b.builder.Constant(true);
     EXPECT_TRUE(c->value->As<constant::Scalar<bool>>()->ValueAs<bool>());
 
-    c->ToString(str, program->Symbols());
+    c->ToString(str, b.builder.ir.symbols);
     EXPECT_EQ("true", str.str());
 
     EXPECT_FALSE(c->value->Is<constant::Scalar<f32>>());
diff --git a/src/tint/ir/debug.cc b/src/tint/ir/debug.cc
index be83111..aaff666 100644
--- a/src/tint/ir/debug.cc
+++ b/src/tint/ir/debug.cc
@@ -23,7 +23,6 @@
 #include "src/tint/ir/loop.h"
 #include "src/tint/ir/switch.h"
 #include "src/tint/ir/terminator.h"
-#include "src/tint/program.h"
 
 namespace tint::ir {
 
@@ -145,8 +144,7 @@
     for (const auto* func : mod->functions) {
         // Cluster each function to label and draw a box around it.
         out << "subgraph cluster_" << name_for(func) << " {" << std::endl;
-        out << R"(label=")" << mod->program->Symbols().NameFor(func->source->symbol) << R"(")"
-            << std::endl;
+        out << R"(label=")" << mod->symbols.NameFor(func->name) << R"(")" << std::endl;
         out << name_for(func->start_target) << R"( [label="start"])" << std::endl;
         out << name_for(func->end_target) << R"( [label="end"])" << std::endl;
         Graph(func->start_target);
diff --git a/src/tint/ir/disassembler.cc b/src/tint/ir/disassembler.cc
index 37f294c..c2b9f98 100644
--- a/src/tint/ir/disassembler.cc
+++ b/src/tint/ir/disassembler.cc
@@ -19,7 +19,6 @@
 #include "src/tint/ir/loop.h"
 #include "src/tint/ir/switch.h"
 #include "src/tint/ir/terminator.h"
-#include "src/tint/program.h"
 
 namespace tint::ir {
 namespace {
@@ -63,7 +62,7 @@
 
 void Disassembler::EmitBlockInstructions(const Block* b) {
     for (const auto* instr : b->instructions) {
-        instr->ToString(out_, mod_.program->Symbols()) << std::endl;
+        instr->ToString(out_, mod_.symbols) << std::endl;
     }
 }
 
diff --git a/src/tint/ir/function.cc b/src/tint/ir/function.cc
index f74550e..167664a 100644
--- a/src/tint/ir/function.cc
+++ b/src/tint/ir/function.cc
@@ -18,7 +18,7 @@
 
 namespace tint::ir {
 
-Function::Function(const ast::Function* f) : Base(), source(f) {}
+Function::Function() : Base() {}
 
 Function::~Function() = default;
 
diff --git a/src/tint/ir/function.h b/src/tint/ir/function.h
index c63aec0..c6032ba 100644
--- a/src/tint/ir/function.h
+++ b/src/tint/ir/function.h
@@ -15,8 +15,8 @@
 #ifndef SRC_TINT_IR_FUNCTION_H_
 #define SRC_TINT_IR_FUNCTION_H_
 
-#include "src/tint/ast/function.h"
 #include "src/tint/ir/flow_node.h"
+#include "src/tint/symbol.h"
 
 // Forward declarations
 namespace tint::ir {
@@ -30,12 +30,11 @@
 class Function : public Castable<Function, FlowNode> {
   public:
     /// Constructor
-    /// @param func the ast::Function to create from
-    explicit Function(const ast::Function* func);
+    Function();
     ~Function() override;
 
-    /// The ast function this ir function is created from.
-    const ast::Function* source;
+    /// The function name
+    Symbol name;
 
     /// The start target is the first block in a function.
     Block* start_target = nullptr;
diff --git a/src/tint/ir/if.cc b/src/tint/ir/if.cc
index df017d2..22a9078 100644
--- a/src/tint/ir/if.cc
+++ b/src/tint/ir/if.cc
@@ -18,7 +18,7 @@
 
 namespace tint::ir {
 
-If::If(const ast::Statement* stmt) : Base(), source(stmt) {}
+If::If() : Base() {}
 
 If::~If() = default;
 
diff --git a/src/tint/ir/if.h b/src/tint/ir/if.h
index 905f311..3a366b3 100644
--- a/src/tint/ir/if.h
+++ b/src/tint/ir/if.h
@@ -15,7 +15,6 @@
 #ifndef SRC_TINT_IR_IF_H_
 #define SRC_TINT_IR_IF_H_
 
-#include "src/tint/ast/if_statement.h"
 #include "src/tint/ir/flow_node.h"
 #include "src/tint/ir/value.h"
 
@@ -30,13 +29,9 @@
 class If : public Castable<If, FlowNode> {
   public:
     /// Constructor
-    /// @param stmt the ast::IfStatement or ast::BreakIfStatement
-    explicit If(const ast::Statement* stmt);
+    If();
     ~If() override;
 
-    /// The ast::IfStatement or ast::BreakIfStatement source for this flow node.
-    const ast::Statement* source;
-
     /// The true branch block
     Block* true_target = nullptr;
     /// The false branch block
diff --git a/src/tint/ir/loop.cc b/src/tint/ir/loop.cc
index 46ac5a1..9a1af45a8 100644
--- a/src/tint/ir/loop.cc
+++ b/src/tint/ir/loop.cc
@@ -14,17 +14,11 @@
 
 #include "src/tint/ir/loop.h"
 
-#include "src/tint/ast/for_loop_statement.h"
-#include "src/tint/ast/loop_statement.h"
-#include "src/tint/ast/while_statement.h"
-
 TINT_INSTANTIATE_TYPEINFO(tint::ir::Loop);
 
 namespace tint::ir {
 
-Loop::Loop(const ast::Statement* s) : Base(), source(s) {
-    TINT_ASSERT(IR, (s->IsAnyOf<ast::LoopStatement, ast::WhileStatement, ast::ForLoopStatement>()));
-}
+Loop::Loop() : Base() {}
 
 Loop::~Loop() = default;
 
diff --git a/src/tint/ir/loop.h b/src/tint/ir/loop.h
index 52d24fb..5db8379 100644
--- a/src/tint/ir/loop.h
+++ b/src/tint/ir/loop.h
@@ -15,7 +15,6 @@
 #ifndef SRC_TINT_IR_LOOP_H_
 #define SRC_TINT_IR_LOOP_H_
 
-#include "src/tint/ast/statement.h"
 #include "src/tint/ir/block.h"
 #include "src/tint/ir/flow_node.h"
 
@@ -25,13 +24,9 @@
 class Loop : public Castable<Loop, FlowNode> {
   public:
     /// Constructor
-    /// @param stmt the loop, while or for statement.
-    explicit Loop(const ast::Statement* stmt);
+    Loop();
     ~Loop() override;
 
-    /// The ast loop, while or for statement this ir loop is created from.
-    const ast::Statement* source;
-
     /// The start block is the first block in a loop.
     Block* start_target = nullptr;
     /// The continue target of the block.
diff --git a/src/tint/ir/module.cc b/src/tint/ir/module.cc
index 0f9be09..bf05e08 100644
--- a/src/tint/ir/module.cc
+++ b/src/tint/ir/module.cc
@@ -34,7 +34,7 @@
     return Result{r.Move()};
 }
 
-Module::Module(const Program* prog) : program(prog) {}
+Module::Module() = default;
 
 Module::Module(Module&&) = default;
 
diff --git a/src/tint/ir/module.h b/src/tint/ir/module.h
index 5e7a9dd..5cfc883 100644
--- a/src/tint/ir/module.h
+++ b/src/tint/ir/module.h
@@ -52,8 +52,7 @@
     static Result FromProgram(const Program* program);
 
     /// Constructor
-    /// @param program the program this module was constructed from
-    explicit Module(const Program* program);
+    Module();
     /// Move constructor
     /// @param o the module to move from
     Module(Module&& o);
@@ -89,9 +88,6 @@
     /// List of indexes into the functions list for the entry points
     utils::Vector<Function*, 8> entry_points;
 
-    /// The source ast::Program this module was constucted from
-    const Program* program;
-
     /// The type manager for the module
     type::Manager types;
 
diff --git a/src/tint/ir/switch.cc b/src/tint/ir/switch.cc
index 23b7fbb..9ad6d30 100644
--- a/src/tint/ir/switch.cc
+++ b/src/tint/ir/switch.cc
@@ -18,7 +18,7 @@
 
 namespace tint::ir {
 
-Switch::Switch(const ast::SwitchStatement* stmt) : Base(), source(stmt) {}
+Switch::Switch() : Base() {}
 
 Switch::~Switch() = default;
 
diff --git a/src/tint/ir/switch.h b/src/tint/ir/switch.h
index 0a8d989..7fad948 100644
--- a/src/tint/ir/switch.h
+++ b/src/tint/ir/switch.h
@@ -20,11 +20,6 @@
 #include "src/tint/ir/flow_node.h"
 #include "src/tint/ir/value.h"
 
-// Forward declarations
-namespace tint::ast {
-class SwitchStatement;
-}  // namespace tint::ast
-
 namespace tint::ir {
 
 /// Flow node representing a switch statement
@@ -48,13 +43,9 @@
     };
 
     /// Constructor
-    /// @param stmt the originating ast switch statement
-    explicit Switch(const ast::SwitchStatement* stmt);
+    Switch();
     ~Switch() override;
 
-    /// The originating switch statment in the AST
-    const ast::SwitchStatement* source;
-
     /// The switch merge target
     Block* merge_target;
 
diff --git a/src/tint/ir/temp_test.cc b/src/tint/ir/temp_test.cc
index 81a4992..ddb0124 100644
--- a/src/tint/ir/temp_test.cc
+++ b/src/tint/ir/temp_test.cc
@@ -33,7 +33,7 @@
     auto* val = b.builder.Temp(b.builder.ir.types.Get<type::I32>());
     EXPECT_EQ(4u, val->AsId());
 
-    val->ToString(str, program->Symbols());
+    val->ToString(str, b.builder.ir.symbols);
     EXPECT_EQ("%4 (i32)", str.str());
 }