[spirv-writer] Move module to SPIR-V builder constructor

This CL moves the ast::Module to the constructor of the SPIR-V builder
class. This allows access to things like the ast::Import from the
builder class.

Bug: tint:5
Change-Id: I0d61b164c1274d006e124dde2cc11f41a2385fc5
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/19922
Reviewed-by: David Neto <dneto@google.com>
diff --git a/src/writer/spirv/binary_writer_test.cc b/src/writer/spirv/binary_writer_test.cc
index f3cf327..4de1aae 100644
--- a/src/writer/spirv/binary_writer_test.cc
+++ b/src/writer/spirv/binary_writer_test.cc
@@ -28,7 +28,8 @@
 using BinaryWriterTest = testing::Test;
 
 TEST_F(BinaryWriterTest, Preamble) {
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   BinaryWriter bw;
   bw.WriteHeader(5);
 
@@ -42,7 +43,8 @@
 }
 
 TEST_F(BinaryWriterTest, Float) {
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   b.push_preamble(spv::Op::OpNop, {Operand::Float(2.4f)});
   BinaryWriter bw;
   bw.WriteBuilder(b);
@@ -55,7 +57,8 @@
 }
 
 TEST_F(BinaryWriterTest, Int) {
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   b.push_preamble(spv::Op::OpNop, {Operand::Int(2)});
   BinaryWriter bw;
   bw.WriteBuilder(b);
@@ -66,7 +69,8 @@
 }
 
 TEST_F(BinaryWriterTest, String) {
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   b.push_preamble(spv::Op::OpNop, {Operand::String("my_string")});
   BinaryWriter bw;
   bw.WriteBuilder(b);
@@ -90,7 +94,8 @@
 }
 
 TEST_F(BinaryWriterTest, String_Multiple4Length) {
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   b.push_preamble(spv::Op::OpNop, {Operand::String("mystring")});
   BinaryWriter bw;
   bw.WriteBuilder(b);
diff --git a/src/writer/spirv/builder.cc b/src/writer/spirv/builder.cc
index ed435dc..19fab5b 100644
--- a/src/writer/spirv/builder.cc
+++ b/src/writer/spirv/builder.cc
@@ -82,16 +82,16 @@
 
 }  // namespace
 
-Builder::Builder() : scope_stack_({}) {}
+Builder::Builder(ast::Module* mod) : mod_(mod), scope_stack_({}) {}
 
 Builder::~Builder() = default;
 
-bool Builder::Build(const ast::Module& m) {
+bool Builder::Build() {
   push_preamble(spv::Op::OpCapability, {Operand::Int(SpvCapabilityShader)});
   push_preamble(spv::Op::OpCapability,
                 {Operand::Int(SpvCapabilityVulkanMemoryModel)});
 
-  for (const auto& imp : m.imports()) {
+  for (const auto& imp : mod_->imports()) {
     GenerateImport(imp.get());
   }
 
@@ -99,19 +99,19 @@
                 {Operand::Int(SpvAddressingModelLogical),
                  Operand::Int(SpvMemoryModelVulkanKHR)});
 
-  for (const auto& var : m.global_variables()) {
+  for (const auto& var : mod_->global_variables()) {
     if (!GenerateGlobalVariable(var.get())) {
       return false;
     }
   }
 
-  for (const auto& func : m.functions()) {
+  for (const auto& func : mod_->functions()) {
     if (!GenerateFunction(func.get())) {
       return false;
     }
   }
 
-  for (const auto& ep : m.entry_points()) {
+  for (const auto& ep : mod_->entry_points()) {
     if (!GenerateEntryPoint(ep.get())) {
       return false;
     }
diff --git a/src/writer/spirv/builder.h b/src/writer/spirv/builder.h
index f1ae870..36f53d0 100644
--- a/src/writer/spirv/builder.h
+++ b/src/writer/spirv/builder.h
@@ -38,13 +38,13 @@
 class Builder {
  public:
   /// Constructor
-  Builder();
+  /// @param mod the module to generate from
+  explicit Builder(ast::Module* mod);
   ~Builder();
 
   /// Generates the SPIR-V instructions for the given module
-  /// @param module the module to generate from
   /// @returns true if the SPIR-V was successfully built
-  bool Build(const ast::Module& module);
+  bool Build();
 
   /// @returns the error string or blank if no error was reported.
   const std::string& error() const { return error_; }
@@ -280,6 +280,7 @@
   /// automatically.
   Operand result_op();
 
+  ast::Module* mod_;
   std::string error_;
   uint32_t next_id_ = 1;
   std::vector<Instruction> preamble_;
diff --git a/src/writer/spirv/builder_assign_test.cc b/src/writer/spirv/builder_assign_test.cc
index 5c7430e..c567386 100644
--- a/src/writer/spirv/builder_assign_test.cc
+++ b/src/writer/spirv/builder_assign_test.cc
@@ -37,7 +37,8 @@
 
   ast::Variable v("var", ast::StorageClass::kOutput, &f32);
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error();
   ASSERT_FALSE(b.has_error()) << b.error();
 
diff --git a/src/writer/spirv/builder_binary_expression_test.cc b/src/writer/spirv/builder_binary_expression_test.cc
index e356454..4d8df69 100644
--- a/src/writer/spirv/builder_binary_expression_test.cc
+++ b/src/writer/spirv/builder_binary_expression_test.cc
@@ -64,7 +64,8 @@
   TypeDeterminer td(&ctx);
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   b.push_function(Function{});
 
   EXPECT_EQ(b.GenerateBinaryExpression(&expr), 4u) << b.error();
@@ -107,7 +108,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   b.push_function(Function{});
 
   EXPECT_EQ(b.GenerateBinaryExpression(&expr), 5u) << b.error();
@@ -152,7 +154,8 @@
   TypeDeterminer td(&ctx);
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   b.push_function(Function{});
 
   EXPECT_EQ(b.GenerateBinaryExpression(&expr), 4u) << b.error();
@@ -195,7 +198,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   b.push_function(Function{});
 
   EXPECT_EQ(b.GenerateBinaryExpression(&expr), 5u) << b.error();
@@ -240,7 +244,8 @@
   TypeDeterminer td(&ctx);
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   b.push_function(Function{});
 
   EXPECT_EQ(b.GenerateBinaryExpression(&expr), 4u) << b.error();
@@ -284,7 +289,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   b.push_function(Function{});
 
   EXPECT_EQ(b.GenerateBinaryExpression(&expr), 5u) << b.error();
@@ -322,7 +328,8 @@
   TypeDeterminer td(&ctx);
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   b.push_function(Function{});
 
   EXPECT_EQ(b.GenerateBinaryExpression(&expr), 4u) << b.error();
@@ -367,7 +374,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   b.push_function(Function{});
 
   EXPECT_EQ(b.GenerateBinaryExpression(&expr), 5u) << b.error();
@@ -409,7 +417,8 @@
   TypeDeterminer td(&ctx);
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   b.push_function(Function{});
 
   EXPECT_EQ(b.GenerateBinaryExpression(&expr), 4u) << b.error();
@@ -454,7 +463,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   b.push_function(Function{});
 
   EXPECT_EQ(b.GenerateBinaryExpression(&expr), 5u) << b.error();
@@ -496,7 +506,8 @@
   TypeDeterminer td(&ctx);
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   b.push_function(Function{});
 
   EXPECT_EQ(b.GenerateBinaryExpression(&expr), 4u) << b.error();
@@ -541,7 +552,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   b.push_function(Function{});
 
   EXPECT_EQ(b.GenerateBinaryExpression(&expr), 5u) << b.error();
@@ -591,7 +603,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   b.push_function(Function{});
 
   EXPECT_EQ(b.GenerateBinaryExpression(&expr), 5u) << b.error();
@@ -629,7 +642,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   b.push_function(Function{});
 
   EXPECT_EQ(b.GenerateBinaryExpression(&expr), 5u) << b.error();
@@ -661,7 +675,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateGlobalVariable(var.get())) << b.error();
 
@@ -698,7 +713,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateGlobalVariable(var.get())) << b.error();
 
@@ -744,7 +760,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateGlobalVariable(var.get())) << b.error();
 
@@ -792,7 +809,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateGlobalVariable(var.get())) << b.error();
 
@@ -830,7 +848,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateGlobalVariable(var.get())) << b.error();
 
diff --git a/src/writer/spirv/builder_constructor_expression_test.cc b/src/writer/spirv/builder_constructor_expression_test.cc
index 5e8f462..0bc3da1 100644
--- a/src/writer/spirv/builder_constructor_expression_test.cc
+++ b/src/writer/spirv/builder_constructor_expression_test.cc
@@ -38,7 +38,8 @@
   auto fl = std::make_unique<ast::FloatLiteral>(&f32, 42.2f);
   ast::ScalarConstructorExpression c(std::move(fl));
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   EXPECT_EQ(b.GenerateConstructorExpression(&c, true), 2u);
   ASSERT_FALSE(b.has_error()) << b.error();
 
@@ -61,7 +62,8 @@
 
   ast::TypeConstructorExpression t(&vec, std::move(vals));
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   EXPECT_EQ(b.GenerateConstructorExpression(&t, true), 5u);
   ASSERT_FALSE(b.has_error()) << b.error();
 
@@ -87,7 +89,8 @@
 
   ast::TypeConstructorExpression t(&vec, std::move(vals));
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   EXPECT_EQ(b.GenerateConstructorExpression(&t, true), 5u);
   EXPECT_EQ(b.GenerateConstructorExpression(&t, true), 5u);
   ASSERT_FALSE(b.has_error()) << b.error();
@@ -110,7 +113,8 @@
 
   ast::TypeConstructorExpression t(&vec, std::move(vals));
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   EXPECT_EQ(b.GenerateConstructorExpression(&t, true), 0u);
   EXPECT_TRUE(b.has_error());
   EXPECT_EQ(b.error(), R"(constructor must be a constant expression)");
diff --git a/src/writer/spirv/builder_entry_point_test.cc b/src/writer/spirv/builder_entry_point_test.cc
index d629d26..71dcfb7 100644
--- a/src/writer/spirv/builder_entry_point_test.cc
+++ b/src/writer/spirv/builder_entry_point_test.cc
@@ -32,7 +32,8 @@
 TEST_F(BuilderTest, EntryPoint) {
   ast::EntryPoint ep(ast::PipelineStage::kFragment, "main", "frag_main");
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   b.set_func_name_to_id("frag_main", 2);
   ASSERT_TRUE(b.GenerateEntryPoint(&ep));
 
@@ -45,7 +46,8 @@
 TEST_F(BuilderTest, EntryPoint_WithoutName) {
   ast::EntryPoint ep(ast::PipelineStage::kCompute, "", "compute_main");
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   b.set_func_name_to_id("compute_main", 3);
   ASSERT_TRUE(b.GenerateEntryPoint(&ep));
 
@@ -59,7 +61,8 @@
 TEST_F(BuilderTest, EntryPoint_BadFunction) {
   ast::EntryPoint ep(ast::PipelineStage::kFragment, "main", "frag_main");
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   EXPECT_FALSE(b.GenerateEntryPoint(&ep));
   EXPECT_EQ(b.error(), "unable to find ID for function: frag_main");
 }
@@ -78,7 +81,8 @@
 
   ast::EntryPoint ep(params.stage, "", "main");
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   b.set_func_name_to_id("main", 3);
   ASSERT_TRUE(b.GenerateEntryPoint(&ep));
 
diff --git a/src/writer/spirv/builder_function_test.cc b/src/writer/spirv/builder_function_test.cc
index f250cfb..cc34a96 100644
--- a/src/writer/spirv/builder_function_test.cc
+++ b/src/writer/spirv/builder_function_test.cc
@@ -33,7 +33,8 @@
   ast::type::VoidType void_type;
   ast::Function func("a_func", {}, &void_type);
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   ASSERT_TRUE(b.GenerateFunction(&func));
 
   EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %3 "a_func"
@@ -56,7 +57,8 @@
   ast::type::VoidType void_type;
   ast::Function func("a_func", {}, &void_type);
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   ASSERT_TRUE(b.GenerateFunction(&func));
   EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
@@ -68,7 +70,8 @@
   ast::Function func1("a_func", {}, &void_type);
   ast::Function func2("b_func", {}, &void_type);
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   ASSERT_TRUE(b.GenerateFunction(&func1));
   ASSERT_TRUE(b.GenerateFunction(&func2));
   EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
diff --git a/src/writer/spirv/builder_function_variable_test.cc b/src/writer/spirv/builder_function_variable_test.cc
index 286470d..38e98bd 100644
--- a/src/writer/spirv/builder_function_variable_test.cc
+++ b/src/writer/spirv/builder_function_variable_test.cc
@@ -44,7 +44,8 @@
   ast::type::F32Type f32;
   ast::Variable v("var", ast::StorageClass::kNone, &f32);
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   b.push_function(Function{});
   EXPECT_TRUE(b.GenerateFunctionVariable(&v)) << b.error();
   EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
@@ -76,7 +77,8 @@
   ast::Variable v("var", ast::StorageClass::kOutput, &f32);
   v.set_constructor(std::move(init));
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   b.push_function(Function{});
   EXPECT_TRUE(b.GenerateFunctionVariable(&v)) << b.error();
   ASSERT_FALSE(b.has_error()) << b.error();
@@ -120,7 +122,8 @@
   ast::Variable v("var", ast::StorageClass::kOutput, &f32);
   v.set_constructor(std::move(init));
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   b.push_function(Function{});
   EXPECT_TRUE(b.GenerateFunctionVariable(&v)) << b.error();
   ASSERT_FALSE(b.has_error()) << b.error();
@@ -162,7 +165,8 @@
   v.set_constructor(std::move(init));
   v.set_is_const(true);
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   EXPECT_TRUE(b.GenerateFunctionVariable(&v)) << b.error();
   ASSERT_FALSE(b.has_error()) << b.error();
 
diff --git a/src/writer/spirv/builder_global_variable_test.cc b/src/writer/spirv/builder_global_variable_test.cc
index 4591925..aad5670 100644
--- a/src/writer/spirv/builder_global_variable_test.cc
+++ b/src/writer/spirv/builder_global_variable_test.cc
@@ -43,7 +43,8 @@
   ast::type::F32Type f32;
   ast::Variable v("var", ast::StorageClass::kNone, &f32);
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error();
   EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
 )");
@@ -57,7 +58,8 @@
   ast::type::F32Type f32;
   ast::Variable v("var", ast::StorageClass::kOutput, &f32);
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error();
   EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
 )");
@@ -85,7 +87,8 @@
   ast::Variable v("var", ast::StorageClass::kOutput, &f32);
   v.set_constructor(std::move(init));
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error();
   ASSERT_FALSE(b.has_error()) << b.error();
 
@@ -120,7 +123,8 @@
   v.set_constructor(std::move(init));
   v.set_is_const(true);
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error();
   ASSERT_FALSE(b.has_error()) << b.error();
 
@@ -142,7 +146,8 @@
   ast::DecoratedVariable dv(std::move(v));
   dv.set_decorations(std::move(decos));
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   EXPECT_TRUE(b.GenerateGlobalVariable(&dv)) << b.error();
   EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
 OpDecorate %1 Location 5
@@ -164,7 +169,8 @@
   ast::DecoratedVariable dv(std::move(v));
   dv.set_decorations(std::move(decos));
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   EXPECT_TRUE(b.GenerateGlobalVariable(&dv)) << b.error();
   EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
 OpDecorate %1 Binding 2
@@ -187,7 +193,8 @@
   ast::DecoratedVariable dv(std::move(v));
   dv.set_decorations(std::move(decos));
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   EXPECT_TRUE(b.GenerateGlobalVariable(&dv)) << b.error();
   EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
 OpDecorate %1 BuiltIn Position
@@ -210,7 +217,8 @@
 TEST_P(BuiltinDataTest, Convert) {
   auto params = GetParam();
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   EXPECT_EQ(b.ConvertBuiltin(params.builtin), params.result);
 }
 INSTANTIATE_TEST_SUITE_P(
diff --git a/src/writer/spirv/builder_ident_expression_test.cc b/src/writer/spirv/builder_ident_expression_test.cc
index 785aef5..81f3330 100644
--- a/src/writer/spirv/builder_ident_expression_test.cc
+++ b/src/writer/spirv/builder_ident_expression_test.cc
@@ -56,7 +56,8 @@
   v.set_constructor(std::move(init));
   v.set_is_const(true);
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error();
   ASSERT_FALSE(b.has_error()) << b.error();
 
@@ -75,7 +76,8 @@
   ast::type::F32Type f32;
   ast::Variable v("var", ast::StorageClass::kOutput, &f32);
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error();
   EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
 )");
@@ -107,7 +109,8 @@
   v.set_constructor(std::move(init));
   v.set_is_const(true);
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   EXPECT_TRUE(b.GenerateFunctionVariable(&v)) << b.error();
   ASSERT_FALSE(b.has_error()) << b.error();
 
@@ -126,7 +129,8 @@
   ast::type::F32Type f32;
   ast::Variable v("var", ast::StorageClass::kNone, &f32);
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   b.push_function(Function{});
   EXPECT_TRUE(b.GenerateFunctionVariable(&v)) << b.error();
   EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
@@ -161,7 +165,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateGlobalVariable(&var)) << b.error();
 
@@ -198,7 +203,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateGlobalVariable(&var)) << b.error();
 
diff --git a/src/writer/spirv/builder_if_test.cc b/src/writer/spirv/builder_if_test.cc
index e7f8bfb..bbb2ff7 100644
--- a/src/writer/spirv/builder_if_test.cc
+++ b/src/writer/spirv/builder_if_test.cc
@@ -50,7 +50,8 @@
   TypeDeterminer td(&ctx);
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   b.push_function(Function{});
 
   EXPECT_TRUE(b.GenerateIfStatement(&expr)) << b.error();
@@ -93,7 +94,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateGlobalVariable(var.get())) << b.error();
 
@@ -155,7 +157,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateGlobalVariable(var.get())) << b.error();
 
@@ -224,7 +227,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateGlobalVariable(var.get())) << b.error();
 
@@ -317,7 +321,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateGlobalVariable(var.get())) << b.error();
 
diff --git a/src/writer/spirv/builder_literal_test.cc b/src/writer/spirv/builder_literal_test.cc
index d87e9b1..a2307ff 100644
--- a/src/writer/spirv/builder_literal_test.cc
+++ b/src/writer/spirv/builder_literal_test.cc
@@ -36,7 +36,8 @@
   ast::type::BoolType bool_type;
   ast::BoolLiteral b_true(&bool_type, true);
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   auto id = b.GenerateLiteralIfNeeded(&b_true);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(2u, id);
@@ -50,7 +51,8 @@
   ast::type::BoolType bool_type;
   ast::BoolLiteral b_false(&bool_type, false);
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   auto id = b.GenerateLiteralIfNeeded(&b_false);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(2u, id);
@@ -65,7 +67,8 @@
   ast::BoolLiteral b_true(&bool_type, true);
   ast::BoolLiteral b_false(&bool_type, false);
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   ASSERT_NE(b.GenerateLiteralIfNeeded(&b_true), 0u);
   ASSERT_FALSE(b.has_error()) << b.error();
   ASSERT_NE(b.GenerateLiteralIfNeeded(&b_false), 0u);
@@ -83,7 +86,8 @@
   ast::type::I32Type i32;
   ast::IntLiteral i(&i32, -23);
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   auto id = b.GenerateLiteralIfNeeded(&i);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(2u, id);
@@ -98,7 +102,8 @@
   ast::IntLiteral i1(&i32, -23);
   ast::IntLiteral i2(&i32, -23);
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   ASSERT_NE(b.GenerateLiteralIfNeeded(&i1), 0u);
   ASSERT_NE(b.GenerateLiteralIfNeeded(&i2), 0u);
   ASSERT_FALSE(b.has_error()) << b.error();
@@ -112,7 +117,8 @@
   ast::type::U32Type u32;
   ast::UintLiteral i(&u32, 23);
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   auto id = b.GenerateLiteralIfNeeded(&i);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(2u, id);
@@ -127,7 +133,8 @@
   ast::UintLiteral i1(&u32, 23);
   ast::UintLiteral i2(&u32, 23);
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   ASSERT_NE(b.GenerateLiteralIfNeeded(&i1), 0u);
   ASSERT_NE(b.GenerateLiteralIfNeeded(&i2), 0u);
   ASSERT_FALSE(b.has_error()) << b.error();
@@ -141,7 +148,8 @@
   ast::type::F32Type f32;
   ast::FloatLiteral i(&f32, 23.245f);
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   auto id = b.GenerateLiteralIfNeeded(&i);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(2u, id);
@@ -156,7 +164,8 @@
   ast::FloatLiteral i1(&f32, 23.245f);
   ast::FloatLiteral i2(&f32, 23.245f);
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   ASSERT_NE(b.GenerateLiteralIfNeeded(&i1), 0u);
   ASSERT_NE(b.GenerateLiteralIfNeeded(&i2), 0u);
   ASSERT_FALSE(b.has_error()) << b.error();
diff --git a/src/writer/spirv/builder_return_test.cc b/src/writer/spirv/builder_return_test.cc
index 91c0f56..e6ab54c 100644
--- a/src/writer/spirv/builder_return_test.cc
+++ b/src/writer/spirv/builder_return_test.cc
@@ -34,7 +34,8 @@
 TEST_F(BuilderTest, Return) {
   ast::ReturnStatement ret;
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   b.push_function(Function{});
   EXPECT_TRUE(b.GenerateReturnStatement(&ret));
   ASSERT_FALSE(b.has_error()) << b.error();
@@ -60,7 +61,8 @@
 
   ast::ReturnStatement ret(std::move(val));
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   b.push_function(Function{});
   EXPECT_TRUE(b.GenerateReturnStatement(&ret));
   ASSERT_FALSE(b.has_error()) << b.error();
diff --git a/src/writer/spirv/builder_test.cc b/src/writer/spirv/builder_test.cc
index 6360d72..c74fc55 100644
--- a/src/writer/spirv/builder_test.cc
+++ b/src/writer/spirv/builder_test.cc
@@ -34,8 +34,8 @@
   ast::Module m;
   m.AddImport(std::make_unique<ast::Import>("GLSL.std.450", "glsl"));
 
-  Builder b;
-  ASSERT_TRUE(b.Build(m));
+  Builder b(&m);
+  ASSERT_TRUE(b.Build());
   ASSERT_EQ(b.preamble().size(), 4u);
 
   EXPECT_EQ(DumpBuilder(b), R"(OpCapability Shader
@@ -47,8 +47,8 @@
 
 TEST_F(BuilderTest, InsertsPreambleWithoutImport) {
   ast::Module m;
-  Builder b;
-  ASSERT_TRUE(b.Build(m));
+  Builder b(&m);
+  ASSERT_TRUE(b.Build());
   EXPECT_EQ(DumpBuilder(b), R"(OpCapability Shader
 OpCapability VulkanMemoryModel
 OpMemoryModel Logical Vulkan
@@ -56,7 +56,8 @@
 }
 
 TEST_F(BuilderTest, TracksIdBounds) {
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
 
   for (size_t i = 0; i < 5; i++) {
     EXPECT_EQ(b.next_id(), i + 1);
diff --git a/src/writer/spirv/builder_type_test.cc b/src/writer/spirv/builder_type_test.cc
index 1e2c79b..544ec02 100644
--- a/src/writer/spirv/builder_type_test.cc
+++ b/src/writer/spirv/builder_type_test.cc
@@ -43,7 +43,8 @@
   ast::type::F32Type f32;
   ast::type::AliasType alias_type("my_type", &f32);
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   auto id = b.GenerateTypeIfNeeded(&alias_type);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(id, 1u);
@@ -58,7 +59,8 @@
   ast::type::F32Type f32;
   ast::type::AliasType alias_type("my_type", &f32);
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   EXPECT_EQ(b.GenerateTypeIfNeeded(&alias_type), 1u);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(b.GenerateTypeIfNeeded(&i32), 2u);
@@ -73,7 +75,8 @@
   ast::type::I32Type i32;
   ast::type::ArrayType ary(&i32);
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   auto id = b.GenerateTypeIfNeeded(&ary);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(1u, id);
@@ -87,7 +90,8 @@
   ast::type::I32Type i32;
   ast::type::ArrayType ary(&i32);
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   EXPECT_EQ(b.GenerateTypeIfNeeded(&ary), 1u);
   EXPECT_EQ(b.GenerateTypeIfNeeded(&ary), 1u);
   ASSERT_FALSE(b.has_error()) << b.error();
@@ -101,7 +105,8 @@
   ast::type::I32Type i32;
   ast::type::ArrayType ary(&i32, 4);
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   auto id = b.GenerateTypeIfNeeded(&ary);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(1u, id);
@@ -117,7 +122,8 @@
   ast::type::I32Type i32;
   ast::type::ArrayType ary(&i32, 4);
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   EXPECT_EQ(b.GenerateTypeIfNeeded(&ary), 1u);
   EXPECT_EQ(b.GenerateTypeIfNeeded(&ary), 1u);
   ASSERT_FALSE(b.has_error()) << b.error();
@@ -132,7 +138,8 @@
 TEST_F(BuilderTest_Type, GenerateBool) {
   ast::type::BoolType bool_type;
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   auto id = b.GenerateTypeIfNeeded(&bool_type);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(id, 1u);
@@ -146,7 +153,8 @@
   ast::type::I32Type i32;
   ast::type::BoolType bool_type;
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   EXPECT_EQ(b.GenerateTypeIfNeeded(&bool_type), 1u);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(b.GenerateTypeIfNeeded(&i32), 2u);
@@ -158,7 +166,8 @@
 TEST_F(BuilderTest_Type, GenerateF32) {
   ast::type::F32Type f32;
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   auto id = b.GenerateTypeIfNeeded(&f32);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(id, 1u);
@@ -172,7 +181,8 @@
   ast::type::I32Type i32;
   ast::type::F32Type f32;
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   EXPECT_EQ(b.GenerateTypeIfNeeded(&f32), 1u);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(b.GenerateTypeIfNeeded(&i32), 2u);
@@ -184,7 +194,8 @@
 TEST_F(BuilderTest_Type, GenerateI32) {
   ast::type::I32Type i32;
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   auto id = b.GenerateTypeIfNeeded(&i32);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(id, 1u);
@@ -198,7 +209,8 @@
   ast::type::I32Type i32;
   ast::type::F32Type f32;
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   EXPECT_EQ(b.GenerateTypeIfNeeded(&i32), 1u);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(b.GenerateTypeIfNeeded(&f32), 2u);
@@ -211,7 +223,8 @@
   ast::type::F32Type f32;
   ast::type::MatrixType mat_type(&f32, 3, 2);
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   auto id = b.GenerateTypeIfNeeded(&mat_type);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(id, 1u);
@@ -227,7 +240,8 @@
   ast::type::I32Type i32;
   ast::type::MatrixType mat_type(&i32, 3, 4);
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   EXPECT_EQ(b.GenerateTypeIfNeeded(&mat_type), 1u);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(b.GenerateTypeIfNeeded(&i32), 3u);
@@ -240,7 +254,8 @@
   ast::type::I32Type i32;
   ast::type::PointerType ptr(&i32, ast::StorageClass::kOutput);
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   auto id = b.GenerateTypeIfNeeded(&ptr);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(1u, id);
@@ -254,7 +269,8 @@
   ast::type::I32Type i32;
   ast::type::PointerType ptr(&i32, ast::StorageClass::kOutput);
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   EXPECT_EQ(b.GenerateTypeIfNeeded(&ptr), 1u);
   EXPECT_EQ(b.GenerateTypeIfNeeded(&ptr), 1u);
 }
@@ -263,7 +279,8 @@
   auto s = std::make_unique<ast::Struct>();
   ast::type::StructType s_type(std::move(s));
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   auto id = b.GenerateTypeIfNeeded(&s_type);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(id, 1u);
@@ -287,7 +304,8 @@
   ast::type::StructType s_type(std::move(s));
   s_type.set_name("my_struct");
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   auto id = b.GenerateTypeIfNeeded(&s_type);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(id, 1u);
@@ -313,7 +331,8 @@
   ast::type::StructType s_type(std::move(s));
   s_type.set_name("my_struct");
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   auto id = b.GenerateTypeIfNeeded(&s_type);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(id, 1u);
@@ -346,7 +365,8 @@
                                          std::move(members));
   ast::type::StructType s_type(std::move(s));
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   auto id = b.GenerateTypeIfNeeded(&s_type);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(id, 1u);
@@ -365,7 +385,8 @@
 TEST_F(BuilderTest_Type, GenerateU32) {
   ast::type::U32Type u32;
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   auto id = b.GenerateTypeIfNeeded(&u32);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(id, 1u);
@@ -379,7 +400,8 @@
   ast::type::U32Type u32;
   ast::type::F32Type f32;
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   EXPECT_EQ(b.GenerateTypeIfNeeded(&u32), 1u);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(b.GenerateTypeIfNeeded(&f32), 2u);
@@ -392,7 +414,8 @@
   ast::type::F32Type f32;
   ast::type::VectorType vec_type(&f32, 3);
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   auto id = b.GenerateTypeIfNeeded(&vec_type);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(id, 1u);
@@ -407,7 +430,8 @@
   ast::type::I32Type i32;
   ast::type::VectorType vec_type(&i32, 3);
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   EXPECT_EQ(b.GenerateTypeIfNeeded(&vec_type), 1u);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(b.GenerateTypeIfNeeded(&i32), 2u);
@@ -419,7 +443,8 @@
 TEST_F(BuilderTest_Type, GenerateVoid) {
   ast::type::VoidType void_type;
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   auto id = b.GenerateTypeIfNeeded(&void_type);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(id, 1u);
@@ -433,7 +458,8 @@
   ast::type::I32Type i32;
   ast::type::VoidType void_type;
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   EXPECT_EQ(b.GenerateTypeIfNeeded(&void_type), 1u);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(b.GenerateTypeIfNeeded(&i32), 2u);
@@ -454,7 +480,8 @@
 TEST_P(PtrDataTest, ConvertStorageClass) {
   auto params = GetParam();
 
-  Builder b;
+  ast::Module mod;
+  Builder b(&mod);
   EXPECT_EQ(b.ConvertStorageClass(params.ast_class), params.result);
 }
 INSTANTIATE_TEST_SUITE_P(
diff --git a/src/writer/spirv/generator.cc b/src/writer/spirv/generator.cc
index a530fd0..c3b5720 100644
--- a/src/writer/spirv/generator.cc
+++ b/src/writer/spirv/generator.cc
@@ -20,12 +20,13 @@
 namespace writer {
 namespace spirv {
 
-Generator::Generator(ast::Module module) : writer::Writer(std::move(module)) {}
+Generator::Generator(ast::Module module)
+    : writer::Writer(std::move(module)), builder_(&module_) {}
 
 Generator::~Generator() = default;
 
 bool Generator::Generate() {
-  if (!builder_.Build(module_)) {
+  if (!builder_.Build()) {
     set_error(builder_.error());
     return false;
   }