test: Add Build() method for tests using ast::Builder

This separates out the usage of the built module from the construction of the module.

Previously, we'd happily interleave generator testing with module construction statements. Once the AST / Program is made immutable, this will no longer be possible.

Bug: tint:390
Change-Id: Ib4538228e93ca816f5bb796d024f021116609213
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/38360
Reviewed-by: dan sinclair <dsinclair@chromium.org>
Commit-Queue: Ben Clayton <bclayton@google.com>
diff --git a/src/validator/validator_control_block_test.cc b/src/validator/validator_control_block_test.cc
index 005abe3..3bfc754 100644
--- a/src/validator/validator_control_block_test.cc
+++ b/src/validator/validator_control_block_test.cc
@@ -57,8 +57,11 @@
   });
 
   EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error();
-  EXPECT_FALSE(v()->ValidateStatements(block));
-  EXPECT_EQ(v()->error(),
+
+  ValidatorImpl& v = Build();
+
+  EXPECT_FALSE(v.ValidateStatements(block));
+  EXPECT_EQ(v.error(),
             "12:34 v-0025: switch statement selector expression must be "
             "of a scalar integer type");
 }
@@ -85,8 +88,11 @@
   });
 
   EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error();
-  EXPECT_FALSE(v()->ValidateStatements(block));
-  EXPECT_EQ(v()->error(),
+
+  ValidatorImpl& v = Build();
+
+  EXPECT_FALSE(v.ValidateStatements(block));
+  EXPECT_EQ(v.error(),
             "12:34 v-0008: switch statement must have exactly one default "
             "clause");
 }
@@ -124,8 +130,11 @@
   });
 
   EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error();
-  EXPECT_FALSE(v()->ValidateStatements(block));
-  EXPECT_EQ(v()->error(),
+
+  ValidatorImpl& v = Build();
+
+  EXPECT_FALSE(v.ValidateStatements(block));
+  EXPECT_EQ(v.error(),
             "12:34 v-0008: switch statement must have exactly one default "
             "clause");
 }
@@ -156,8 +165,11 @@
       create<ast::SwitchStatement>(Expr("a"), switch_body),
   });
   EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error();
-  EXPECT_FALSE(v()->ValidateStatements(block));
-  EXPECT_EQ(v()->error(),
+
+  ValidatorImpl& v = Build();
+
+  EXPECT_FALSE(v.ValidateStatements(block));
+  EXPECT_EQ(v.error(),
             "12:34 v-0026: the case selector values must have the same "
             "type as the selector expression.");
 }
@@ -188,8 +200,11 @@
       create<ast::SwitchStatement>(Expr("a"), switch_body),
   });
   EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error();
-  EXPECT_FALSE(v()->ValidateStatements(block));
-  EXPECT_EQ(v()->error(),
+
+  ValidatorImpl& v = Build();
+
+  EXPECT_FALSE(v.ValidateStatements(block));
+  EXPECT_EQ(v.error(),
             "12:34 v-0026: the case selector values must have the same "
             "type as the selector expression.");
 }
@@ -226,8 +241,11 @@
       create<ast::SwitchStatement>(Expr("a"), switch_body),
   });
   EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error();
-  EXPECT_FALSE(v()->ValidateStatements(block));
-  EXPECT_EQ(v()->error(),
+
+  ValidatorImpl& v = Build();
+
+  EXPECT_FALSE(v.ValidateStatements(block));
+  EXPECT_EQ(v.error(),
             "12:34 v-0027: a literal value must not appear more than once "
             "in the case selectors for a switch statement: '2'");
 }
@@ -266,8 +284,11 @@
       create<ast::SwitchStatement>(Expr("a"), switch_body),
   });
   EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error();
-  EXPECT_FALSE(v()->ValidateStatements(block));
-  EXPECT_EQ(v()->error(),
+
+  ValidatorImpl& v = Build();
+
+  EXPECT_FALSE(v.ValidateStatements(block));
+  EXPECT_EQ(v.error(),
             "12:34 v-0027: a literal value must not appear more than once in "
             "the case selectors for a switch statement: '10'");
 }
@@ -294,8 +315,11 @@
       create<ast::SwitchStatement>(Expr("a"), body),
   });
   EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error();
-  EXPECT_FALSE(v()->ValidateStatements(block));
-  EXPECT_EQ(v()->error(),
+
+  ValidatorImpl& v = Build();
+
+  EXPECT_FALSE(v.ValidateStatements(block));
+  EXPECT_EQ(v.error(),
             "12:34 v-0028: a fallthrough statement must not appear as the "
             "last statement in last clause of a switch");
 }
@@ -324,7 +348,10 @@
       create<ast::SwitchStatement>(Expr("a"), body),
   });
   EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error();
-  EXPECT_TRUE(v()->ValidateStatements(block)) << v()->error();
+
+  ValidatorImpl& v = Build();
+
+  EXPECT_TRUE(v.ValidateStatements(block)) << v.error();
 }
 
 TEST_F(ValidateControlBlockTest, SwitchCaseAlias_Pass) {
@@ -351,7 +378,10 @@
   mod->AddConstructedType(my_int);
 
   EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error();
-  EXPECT_TRUE(v()->ValidateStatements(block)) << v()->error();
+
+  ValidatorImpl& v = Build();
+
+  EXPECT_TRUE(v.ValidateStatements(block)) << v.error();
 }
 
 }  // namespace
diff --git a/src/validator/validator_function_test.cc b/src/validator/validator_function_test.cc
index c5379ba..1ca339f 100644
--- a/src/validator/validator_function_test.cc
+++ b/src/validator/validator_function_test.cc
@@ -52,7 +52,10 @@
   mod->AddFunction(func);
 
   EXPECT_TRUE(td()->Determine()) << td()->error();
-  EXPECT_TRUE(v()->Validate());
+
+  ValidatorImpl& v = Build();
+
+  EXPECT_TRUE(v.Validate());
 }
 
 TEST_F(ValidateFunctionTest,
@@ -68,7 +71,10 @@
   mod->AddFunction(func);
 
   EXPECT_TRUE(td()->Determine()) << td()->error();
-  EXPECT_TRUE(v()->Validate());
+
+  ValidatorImpl& v = Build();
+
+  EXPECT_TRUE(v.Validate());
 }
 
 TEST_F(ValidateFunctionTest, FunctionEndWithoutReturnStatement_Fail) {
@@ -86,8 +92,11 @@
   mod->AddFunction(func);
 
   EXPECT_TRUE(td()->Determine()) << td()->error();
-  EXPECT_FALSE(v()->Validate());
-  EXPECT_EQ(v()->error(),
+
+  ValidatorImpl& v = Build();
+
+  EXPECT_FALSE(v.Validate());
+  EXPECT_EQ(v.error(),
             "12:34 v-0002: non-void function must end with a return statement");
 }
 
@@ -99,8 +108,11 @@
   mod->AddFunction(func);
 
   EXPECT_TRUE(td()->Determine()) << td()->error();
-  EXPECT_FALSE(v()->Validate());
-  EXPECT_EQ(v()->error(),
+
+  ValidatorImpl& v = Build();
+
+  EXPECT_FALSE(v.Validate());
+  EXPECT_EQ(v.error(),
             "12:34 v-0002: non-void function must end with a return statement");
 }
 
@@ -118,7 +130,10 @@
   mod->AddFunction(func);
 
   EXPECT_TRUE(td()->DetermineFunctions(mod->functions())) << td()->error();
-  EXPECT_TRUE(v()->ValidateFunctions(mod->functions())) << v()->error();
+
+  ValidatorImpl& v = Build();
+
+  EXPECT_TRUE(v.ValidateFunctions(mod->functions())) << v.error();
 }
 
 TEST_F(ValidateFunctionTest, FunctionTypeMustMatchReturnStatementType_fail) {
@@ -132,9 +147,12 @@
   mod->AddFunction(func);
 
   EXPECT_TRUE(td()->Determine()) << td()->error();
-  EXPECT_FALSE(v()->Validate());
+
+  ValidatorImpl& v = Build();
+
+  EXPECT_FALSE(v.Validate());
   // TODO(sarahM0): replace 000y with a rule number
-  EXPECT_EQ(v()->error(),
+  EXPECT_EQ(v.error(),
             "12:34 v-000y: return statement type must match its function "
             "return type, returned '__i32', expected '__void'");
 }
@@ -150,9 +168,12 @@
   mod->AddFunction(func);
 
   EXPECT_TRUE(td()->Determine()) << td()->error();
-  EXPECT_FALSE(v()->Validate());
+
+  ValidatorImpl& v = Build();
+
+  EXPECT_FALSE(v.Validate());
   // TODO(sarahM0): replace 000y with a rule number
-  EXPECT_EQ(v()->error(),
+  EXPECT_EQ(v.error(),
             "12:34 v-000y: return statement type must match its function "
             "return type, returned '__i32', expected '__f32'");
 }
@@ -177,8 +198,11 @@
   mod->AddFunction(func_copy);
 
   EXPECT_TRUE(td()->Determine()) << td()->error();
-  EXPECT_FALSE(v()->Validate());
-  EXPECT_EQ(v()->error(), "12:34 v-0016: function names must be unique 'func'");
+
+  ValidatorImpl& v = Build();
+
+  EXPECT_FALSE(v.Validate());
+  EXPECT_EQ(v.error(), "12:34 v-0016: function names must be unique 'func'");
 }
 
 TEST_F(ValidateFunctionTest, RecursionIsNotAllowed_Fail) {
@@ -196,8 +220,11 @@
   mod->AddFunction(func0);
 
   EXPECT_TRUE(td()->Determine()) << td()->error();
-  EXPECT_FALSE(v()->Validate()) << v()->error();
-  EXPECT_EQ(v()->error(), "12:34 v-0004: recursion is not allowed: 'func'");
+
+  ValidatorImpl& v = Build();
+
+  EXPECT_FALSE(v.Validate()) << v.error();
+  EXPECT_EQ(v.error(), "12:34 v-0004: recursion is not allowed: 'func'");
 }
 
 TEST_F(ValidateFunctionTest, RecursionIsNotAllowedExpr_Fail) {
@@ -217,8 +244,11 @@
   mod->AddFunction(func0);
 
   EXPECT_TRUE(td()->Determine()) << td()->error();
-  EXPECT_FALSE(v()->Validate()) << v()->error();
-  EXPECT_EQ(v()->error(), "12:34 v-0004: recursion is not allowed: 'func'");
+
+  ValidatorImpl& v = Build();
+
+  EXPECT_FALSE(v.Validate()) << v.error();
+  EXPECT_EQ(v.error(), "12:34 v-0004: recursion is not allowed: 'func'");
 }
 
 TEST_F(ValidateFunctionTest, Function_WithPipelineStage_NotVoid_Fail) {
@@ -235,8 +265,11 @@
 
   mod->AddFunction(func);
   EXPECT_TRUE(td()->Determine()) << td()->error();
-  EXPECT_FALSE(v()->Validate());
-  EXPECT_EQ(v()->error(),
+
+  ValidatorImpl& v = Build();
+
+  EXPECT_FALSE(v.Validate());
+  EXPECT_EQ(v.error(),
             "12:34 v-0024: Entry point function must return void: 'vtx_main'");
 }
 
@@ -257,8 +290,11 @@
 
   mod->AddFunction(func);
   EXPECT_TRUE(td()->Determine()) << td()->error();
-  EXPECT_FALSE(v()->Validate());
-  EXPECT_EQ(v()->error(),
+
+  ValidatorImpl& v = Build();
+
+  EXPECT_FALSE(v.Validate());
+  EXPECT_EQ(v.error(),
             "12:34 v-0023: Entry point function must accept no parameters: "
             "'vtx_func'");
 }
@@ -279,9 +315,12 @@
 
   mod->AddFunction(func);
   EXPECT_TRUE(td()->Determine()) << td()->error();
-  EXPECT_FALSE(v()->Validate());
+
+  ValidatorImpl& v = Build();
+
+  EXPECT_FALSE(v.Validate());
   EXPECT_EQ(
-      v()->error(),
+      v.error(),
       "12:34 v-0020: only one stage decoration permitted per entry point");
 }
 
@@ -299,7 +338,10 @@
   mod->AddFunction(func);
 
   EXPECT_TRUE(td()->Determine()) << td()->error();
-  EXPECT_TRUE(v()->Validate()) << v()->error();
+
+  ValidatorImpl& v = Build();
+
+  EXPECT_TRUE(v.Validate()) << v.error();
 }
 
 TEST_F(ValidateFunctionTest, OnePipelineStageFunctionMustBePresent_Fail) {
@@ -312,8 +354,11 @@
   mod->AddFunction(func);
 
   EXPECT_TRUE(td()->Determine()) << td()->error();
-  EXPECT_FALSE(v()->Validate());
-  EXPECT_EQ(v()->error(),
+
+  ValidatorImpl& v = Build();
+
+  EXPECT_FALSE(v.Validate());
+  EXPECT_EQ(v.error(),
             "v-0003: At least one of vertex, fragment or compute shader must "
             "be present");
 }
diff --git a/src/validator/validator_test.cc b/src/validator/validator_test.cc
index 7973dc7..a4a03d1 100644
--- a/src/validator/validator_test.cc
+++ b/src/validator/validator_test.cc
@@ -73,12 +73,14 @@
   auto* assign = create<ast::AssignmentStatement>(lhs, rhs);
   RegisterVariable(var);
 
+  ValidatorImpl& v = Build();
+
   EXPECT_TRUE(td()->DetermineResultType(assign));
   // TODO(sarahM0): Invalidate assignment to scalar.
-  EXPECT_FALSE(v()->ValidateAssign(assign));
-  ASSERT_TRUE(v()->has_error());
+  EXPECT_FALSE(v.ValidateAssign(assign));
+  ASSERT_TRUE(v.has_error());
   // TODO(sarahM0): figure out what should be the error number.
-  EXPECT_EQ(v()->error(),
+  EXPECT_EQ(v.error(),
             "12:34 v-000x: invalid assignment: left-hand-side does not "
             "reference storage: __i32");
 }
@@ -129,7 +131,9 @@
   EXPECT_TRUE(td()->DetermineResultType(assign)) << td()->error();
   ASSERT_NE(lhs->result_type(), nullptr);
   ASSERT_NE(rhs->result_type(), nullptr);
-  EXPECT_TRUE(v()->ValidateAssign(assign)) << v()->error();
+  ValidatorImpl& v = Build();
+
+  EXPECT_TRUE(v.ValidateAssign(assign)) << v.error();
 }
 
 TEST_F(ValidatorTest, AssignCompatibleTypesThroughAlias_Pass) {
@@ -149,7 +153,9 @@
   EXPECT_TRUE(td()->DetermineResultType(assign)) << td()->error();
   ASSERT_NE(lhs->result_type(), nullptr);
   ASSERT_NE(rhs->result_type(), nullptr);
-  EXPECT_TRUE(v()->ValidateAssign(assign)) << v()->error();
+  ValidatorImpl& v = Build();
+
+  EXPECT_TRUE(v.ValidateAssign(assign)) << v.error();
 }
 
 TEST_F(ValidatorTest, AssignCompatibleTypesInferRHSLoad_Pass) {
@@ -171,7 +177,9 @@
   EXPECT_TRUE(td()->DetermineResultType(assign)) << td()->error();
   ASSERT_NE(lhs->result_type(), nullptr);
   ASSERT_NE(rhs->result_type(), nullptr);
-  EXPECT_TRUE(v()->ValidateAssign(assign)) << v()->error();
+  ValidatorImpl& v = Build();
+
+  EXPECT_TRUE(v.ValidateAssign(assign)) << v.error();
 }
 
 TEST_F(ValidatorTest, AssignThroughPointer_Pass) {
@@ -193,7 +201,10 @@
   EXPECT_TRUE(td()->DetermineResultType(assign)) << td()->error();
   ASSERT_NE(lhs->result_type(), nullptr);
   ASSERT_NE(rhs->result_type(), nullptr);
-  EXPECT_TRUE(v()->ValidateAssign(assign)) << v()->error();
+
+  ValidatorImpl& v = Build();
+
+  EXPECT_TRUE(v.ValidateAssign(assign)) << v.error();
 }
 
 TEST_F(ValidatorTest, AssignIncompatibleTypes_Fail) {
@@ -215,10 +226,12 @@
   ASSERT_NE(lhs->result_type(), nullptr);
   ASSERT_NE(rhs->result_type(), nullptr);
 
-  EXPECT_FALSE(v()->ValidateAssign(assign));
-  ASSERT_TRUE(v()->has_error());
+  ValidatorImpl& v = Build();
+
+  EXPECT_FALSE(v.ValidateAssign(assign));
+  ASSERT_TRUE(v.has_error());
   // TODO(sarahM0): figure out what should be the error number.
-  EXPECT_EQ(v()->error(),
+  EXPECT_EQ(v.error(),
             "12:34 v-000x: invalid assignment: can't assign value of type "
             "'__f32' to '__i32'");
 }
@@ -242,8 +255,11 @@
   EXPECT_TRUE(td()->DetermineResultType(assign)) << td()->error();
   ASSERT_NE(lhs->result_type(), nullptr);
   ASSERT_NE(rhs->result_type(), nullptr);
-  EXPECT_FALSE(v()->ValidateAssign(assign));
-  EXPECT_EQ(v()->error(),
+
+  ValidatorImpl& v = Build();
+
+  EXPECT_FALSE(v.ValidateAssign(assign));
+  EXPECT_EQ(v.error(),
             "12:34 v-000x: invalid assignment: can't assign value of type "
             "'__i32' to '__f32'");
 }
@@ -269,7 +285,9 @@
   ASSERT_NE(lhs->result_type(), nullptr);
   ASSERT_NE(rhs->result_type(), nullptr);
 
-  EXPECT_TRUE(v()->ValidateStatements(body)) << v()->error();
+  ValidatorImpl& v = Build();
+
+  EXPECT_TRUE(v.ValidateStatements(body)) << v.error();
 }
 
 TEST_F(ValidatorTest, AssignIncompatibleTypesInBlockStatement_Fail) {
@@ -294,10 +312,12 @@
   ASSERT_NE(lhs->result_type(), nullptr);
   ASSERT_NE(rhs->result_type(), nullptr);
 
-  EXPECT_FALSE(v()->ValidateStatements(block));
-  ASSERT_TRUE(v()->has_error());
+  ValidatorImpl& v = Build();
+
+  EXPECT_FALSE(v.ValidateStatements(block));
+  ASSERT_TRUE(v.has_error());
   // TODO(sarahM0): figure out what should be the error number.
-  EXPECT_EQ(v()->error(),
+  EXPECT_EQ(v.error(),
             "12:34 v-000x: invalid assignment: can't assign value of type "
             "'__f32' to '__i32'");
 }
@@ -307,8 +327,10 @@
   mod->AddGlobalVariable(Var(Source{Source::Location{12, 34}}, "global_var",
                              ast::StorageClass::kInput, ty.f32, nullptr,
                              ast::VariableDecorationList{}));
-  EXPECT_TRUE(v()->ValidateGlobalVariables(mod->global_variables()))
-      << v()->error();
+
+  ValidatorImpl& v = Build();
+
+  EXPECT_TRUE(v.ValidateGlobalVariables(mod->global_variables())) << v.error();
 }
 
 TEST_F(ValidatorTest, GlobalVariableNoStorageClass_Fail) {
@@ -317,8 +339,11 @@
                              ast::StorageClass::kNone, ty.f32, nullptr,
                              ast::VariableDecorationList{}));
   EXPECT_TRUE(td()->Determine()) << td()->error();
-  EXPECT_FALSE(v()->Validate());
-  EXPECT_EQ(v()->error(),
+
+  ValidatorImpl& v = Build();
+
+  EXPECT_FALSE(v.Validate());
+  EXPECT_EQ(v.error(),
             "12:34 v-0022: global variables must have a storage class");
 }
 
@@ -328,9 +353,12 @@
                                ast::StorageClass::kInput, ty.f32, nullptr,
                                ast::VariableDecorationList{}));
   EXPECT_TRUE(td()->Determine()) << td()->error();
-  EXPECT_FALSE(v()->Validate());
+
+  ValidatorImpl& v = Build();
+
+  EXPECT_FALSE(v.Validate());
   EXPECT_EQ(
-      v()->error(),
+      v.error(),
       "12:34 v-global01: global constants shouldn't have a storage class");
 }
 
@@ -340,7 +368,10 @@
                                ast::StorageClass::kNone, ty.f32, nullptr,
                                ast::VariableDecorationList{}));
   EXPECT_TRUE(td()->Determine()) << td()->error();
-  EXPECT_FALSE(v()->Validate()) << v()->error();
+
+  ValidatorImpl& v = Build();
+
+  EXPECT_FALSE(v.Validate()) << v.error();
 }
 
 TEST_F(ValidatorTest, UsingUndefinedVariableGlobalVariable_Fail) {
@@ -363,8 +394,10 @@
                     ast::FunctionDecorationList{});
   mod->AddFunction(func);
 
-  EXPECT_FALSE(v()->Validate());
-  EXPECT_EQ(v()->error(), "12:34 v-0006: 'not_global_var' is not declared");
+  ValidatorImpl& v = Build();
+
+  EXPECT_FALSE(v.Validate());
+  EXPECT_EQ(v.error(), "12:34 v-0006: 'not_global_var' is not declared");
 }
 
 TEST_F(ValidatorTest, UsingUndefinedVariableGlobalVariable_Pass) {
@@ -390,7 +423,10 @@
   mod->AddFunction(func);
 
   EXPECT_TRUE(td()->Determine()) << td()->error();
-  EXPECT_TRUE(v()->Validate()) << v()->error();
+
+  ValidatorImpl& v = Build();
+
+  EXPECT_TRUE(v.Validate()) << v.error();
 }
 
 TEST_F(ValidatorTest, UsingUndefinedVariableInnerScope_Fail) {
@@ -419,8 +455,11 @@
   EXPECT_TRUE(td()->DetermineStatements(outer_body)) << td()->error();
   ASSERT_NE(lhs->result_type(), nullptr);
   ASSERT_NE(rhs->result_type(), nullptr);
-  EXPECT_FALSE(v()->ValidateStatements(outer_body));
-  EXPECT_EQ(v()->error(), "12:34 v-0006: 'a' is not declared");
+
+  ValidatorImpl& v = Build();
+
+  EXPECT_FALSE(v.ValidateStatements(outer_body));
+  EXPECT_EQ(v.error(), "12:34 v-0006: 'a' is not declared");
 }
 
 TEST_F(ValidatorTest, UsingUndefinedVariableOuterScope_Pass) {
@@ -449,7 +488,10 @@
   EXPECT_TRUE(td()->DetermineStatements(outer_body)) << td()->error();
   ASSERT_NE(lhs->result_type(), nullptr);
   ASSERT_NE(rhs->result_type(), nullptr);
-  EXPECT_TRUE(v()->ValidateStatements(outer_body)) << v()->error();
+
+  ValidatorImpl& v = Build();
+
+  EXPECT_TRUE(v.ValidateStatements(outer_body)) << v.error();
 }
 
 TEST_F(ValidatorTest, GlobalVariableUnique_Pass) {
@@ -464,8 +506,9 @@
                    ast::VariableDecorationList{});
   mod->AddGlobalVariable(var1);
 
-  EXPECT_TRUE(v()->ValidateGlobalVariables(mod->global_variables()))
-      << v()->error();
+  ValidatorImpl& v = Build();
+
+  EXPECT_TRUE(v.ValidateGlobalVariables(mod->global_variables())) << v.error();
 }
 
 TEST_F(ValidatorTest, GlobalVariableNotUnique_Fail) {
@@ -480,8 +523,10 @@
                    ast::VariableDecorationList{});
   mod->AddGlobalVariable(var1);
 
-  EXPECT_FALSE(v()->ValidateGlobalVariables(mod->global_variables()));
-  EXPECT_EQ(v()->error(),
+  ValidatorImpl& v = Build();
+
+  EXPECT_FALSE(v.ValidateGlobalVariables(mod->global_variables()));
+  EXPECT_EQ(v.error(),
             "12:34 v-0011: redeclared global identifier 'global_var'");
 }
 
@@ -506,8 +551,10 @@
   ASSERT_NE(lhs->result_type(), nullptr);
   ASSERT_NE(rhs->result_type(), nullptr);
 
-  EXPECT_FALSE(v()->ValidateStatements(body));
-  EXPECT_EQ(v()->error(), "12:34 v-0021: cannot re-assign a constant: 'a'");
+  ValidatorImpl& v = Build();
+
+  EXPECT_FALSE(v.ValidateStatements(body));
+  EXPECT_EQ(v.error(), "12:34 v-0021: cannot re-assign a constant: 'a'");
 }
 
 TEST_F(ValidatorTest, GlobalVariableFunctionVariableNotUnique_Fail) {
@@ -535,8 +582,11 @@
 
   EXPECT_TRUE(td()->Determine()) << td()->error();
   EXPECT_TRUE(td()->DetermineFunction(func)) << td()->error();
-  EXPECT_FALSE(v()->Validate()) << v()->error();
-  EXPECT_EQ(v()->error(), "12:34 v-0013: redeclared identifier 'a'");
+
+  ValidatorImpl& v = Build();
+
+  EXPECT_FALSE(v.Validate()) << v.error();
+  EXPECT_EQ(v.error(), "12:34 v-0013: redeclared identifier 'a'");
 }
 
 TEST_F(ValidatorTest, RedeclaredIndentifier_Fail) {
@@ -562,8 +612,11 @@
 
   EXPECT_TRUE(td()->Determine()) << td()->error();
   EXPECT_TRUE(td()->DetermineFunction(func)) << td()->error();
-  EXPECT_FALSE(v()->Validate());
-  EXPECT_EQ(v()->error(), "12:34 v-0014: redeclared identifier 'a'");
+
+  ValidatorImpl& v = Build();
+
+  EXPECT_FALSE(v.Validate());
+  EXPECT_EQ(v.error(), "12:34 v-0014: redeclared identifier 'a'");
 }
 
 TEST_F(ValidatorTest, RedeclaredIdentifierInnerScope_Pass) {
@@ -589,7 +642,10 @@
   });
 
   EXPECT_TRUE(td()->DetermineStatements(outer_body)) << td()->error();
-  EXPECT_TRUE(v()->ValidateStatements(outer_body)) << v()->error();
+
+  ValidatorImpl& v = Build();
+
+  EXPECT_TRUE(v.ValidateStatements(outer_body)) << v.error();
 }
 
 TEST_F(ValidatorTest, DISABLED_RedeclaredIdentifierInnerScope_False) {
@@ -616,8 +672,11 @@
   });
 
   EXPECT_TRUE(td()->DetermineStatements(outer_body)) << td()->error();
-  EXPECT_FALSE(v()->ValidateStatements(outer_body));
-  EXPECT_EQ(v()->error(), "12:34 v-0014: redeclared identifier 'a'");
+
+  ValidatorImpl& v = Build();
+
+  EXPECT_FALSE(v.ValidateStatements(outer_body));
+  EXPECT_EQ(v.error(), "12:34 v-0014: redeclared identifier 'a'");
 }
 
 TEST_F(ValidatorTest, RedeclaredIdentifierDifferentFunctions_Pass) {
@@ -652,7 +711,10 @@
   mod->AddFunction(func1);
 
   EXPECT_TRUE(td()->Determine()) << td()->error();
-  EXPECT_TRUE(v()->Validate()) << v()->error();
+
+  ValidatorImpl& v = Build();
+
+  EXPECT_TRUE(v.Validate()) << v.error();
 }
 
 TEST_F(ValidatorTest, VariableDeclNoConstructor_Pass) {
@@ -676,80 +738,107 @@
   EXPECT_TRUE(td()->DetermineStatements(body)) << td()->error();
   ASSERT_NE(lhs->result_type(), nullptr);
   ASSERT_NE(rhs->result_type(), nullptr);
-  EXPECT_TRUE(v()->ValidateStatements(body)) << v()->error();
+
+  ValidatorImpl& v = Build();
+
+  EXPECT_TRUE(v.ValidateStatements(body)) << v.error();
 }
 
 TEST_F(ValidatorTest, IsStorable_Void) {
-  EXPECT_FALSE(v()->IsStorable(ty.void_));
+  ValidatorImpl& v = Build();
+
+  EXPECT_FALSE(v.IsStorable(ty.void_));
 }
 
 TEST_F(ValidatorTest, IsStorable_Scalar) {
-  EXPECT_TRUE(v()->IsStorable(ty.bool_));
-  EXPECT_TRUE(v()->IsStorable(ty.i32));
-  EXPECT_TRUE(v()->IsStorable(ty.u32));
-  EXPECT_TRUE(v()->IsStorable(ty.f32));
+  ValidatorImpl& v = Build();
+
+  EXPECT_TRUE(v.IsStorable(ty.bool_));
+  EXPECT_TRUE(v.IsStorable(ty.i32));
+  EXPECT_TRUE(v.IsStorable(ty.u32));
+  EXPECT_TRUE(v.IsStorable(ty.f32));
 }
 
 TEST_F(ValidatorTest, IsStorable_Vector) {
-  EXPECT_TRUE(v()->IsStorable(ty.vec2<int>()));
-  EXPECT_TRUE(v()->IsStorable(ty.vec3<int>()));
-  EXPECT_TRUE(v()->IsStorable(ty.vec4<int>()));
-  EXPECT_TRUE(v()->IsStorable(ty.vec2<unsigned>()));
-  EXPECT_TRUE(v()->IsStorable(ty.vec3<unsigned>()));
-  EXPECT_TRUE(v()->IsStorable(ty.vec4<unsigned>()));
-  EXPECT_TRUE(v()->IsStorable(ty.vec2<float>()));
-  EXPECT_TRUE(v()->IsStorable(ty.vec3<float>()));
-  EXPECT_TRUE(v()->IsStorable(ty.vec4<float>()));
+  ValidatorImpl& v = Build();
+
+  EXPECT_TRUE(v.IsStorable(ty.vec2<int>()));
+  EXPECT_TRUE(v.IsStorable(ty.vec3<int>()));
+  EXPECT_TRUE(v.IsStorable(ty.vec4<int>()));
+  EXPECT_TRUE(v.IsStorable(ty.vec2<unsigned>()));
+  EXPECT_TRUE(v.IsStorable(ty.vec3<unsigned>()));
+  EXPECT_TRUE(v.IsStorable(ty.vec4<unsigned>()));
+  EXPECT_TRUE(v.IsStorable(ty.vec2<float>()));
+  EXPECT_TRUE(v.IsStorable(ty.vec3<float>()));
+  EXPECT_TRUE(v.IsStorable(ty.vec4<float>()));
 }
 
 TEST_F(ValidatorTest, IsStorable_Matrix) {
-  EXPECT_TRUE(v()->IsStorable(ty.mat2x2<float>()));
-  EXPECT_TRUE(v()->IsStorable(ty.mat2x3<float>()));
-  EXPECT_TRUE(v()->IsStorable(ty.mat2x4<float>()));
-  EXPECT_TRUE(v()->IsStorable(ty.mat3x2<float>()));
-  EXPECT_TRUE(v()->IsStorable(ty.mat3x3<float>()));
-  EXPECT_TRUE(v()->IsStorable(ty.mat3x4<float>()));
-  EXPECT_TRUE(v()->IsStorable(ty.mat4x2<float>()));
-  EXPECT_TRUE(v()->IsStorable(ty.mat4x3<float>()));
-  EXPECT_TRUE(v()->IsStorable(ty.mat4x4<float>()));
+  ValidatorImpl& v = Build();
+
+  EXPECT_TRUE(v.IsStorable(ty.mat2x2<float>()));
+  EXPECT_TRUE(v.IsStorable(ty.mat2x3<float>()));
+  EXPECT_TRUE(v.IsStorable(ty.mat2x4<float>()));
+  EXPECT_TRUE(v.IsStorable(ty.mat3x2<float>()));
+  EXPECT_TRUE(v.IsStorable(ty.mat3x3<float>()));
+  EXPECT_TRUE(v.IsStorable(ty.mat3x4<float>()));
+  EXPECT_TRUE(v.IsStorable(ty.mat4x2<float>()));
+  EXPECT_TRUE(v.IsStorable(ty.mat4x3<float>()));
+  EXPECT_TRUE(v.IsStorable(ty.mat4x4<float>()));
 }
 
 TEST_F(ValidatorTest, IsStorable_Pointer) {
   auto* ptr_ty = ty.pointer<int>(ast::StorageClass::kPrivate);
-  EXPECT_FALSE(v()->IsStorable(ptr_ty));
+  ValidatorImpl& v = Build();
+
+  EXPECT_FALSE(v.IsStorable(ptr_ty));
 }
 
 TEST_F(ValidatorTest, IsStorable_AliasVoid) {
   auto* alias = ty.alias("myalias", ty.void_);
-  EXPECT_FALSE(v()->IsStorable(alias));
+  ValidatorImpl& v = Build();
+
+  EXPECT_FALSE(v.IsStorable(alias));
 }
 
 TEST_F(ValidatorTest, IsStorable_AliasI32) {
   auto* alias = ty.alias("myalias", ty.i32);
-  EXPECT_TRUE(v()->IsStorable(alias));
+  ValidatorImpl& v = Build();
+
+  EXPECT_TRUE(v.IsStorable(alias));
 }
 
 TEST_F(ValidatorTest, IsStorable_ArraySizedOfStorable) {
-  EXPECT_TRUE(v()->IsStorable(ty.array(ty.i32, 5)));
+  ValidatorImpl& v = Build();
+
+  EXPECT_TRUE(v.IsStorable(ty.array(ty.i32, 5)));
 }
 
 TEST_F(ValidatorTest, IsStorable_ArraySizedOfNonStorable) {
-  EXPECT_FALSE(v()->IsStorable(ty.array(ty.void_, 5)));
+  ValidatorImpl& v = Build();
+
+  EXPECT_FALSE(v.IsStorable(ty.array(ty.void_, 5)));
 }
 
 TEST_F(ValidatorTest, IsStorable_ArrayUnsizedOfStorable) {
-  EXPECT_TRUE(v()->IsStorable(ty.array<int>()));
+  ValidatorImpl& v = Build();
+
+  EXPECT_TRUE(v.IsStorable(ty.array<int>()));
 }
 
 TEST_F(ValidatorTest, IsStorable_ArrayUnsizedOfNonStorable) {
-  EXPECT_FALSE(v()->IsStorable(ty.array<void>()));
+  ValidatorImpl& v = Build();
+
+  EXPECT_FALSE(v.IsStorable(ty.array<void>()));
 }
 
 TEST_F(ValidatorTest, IsStorable_Struct_AllMembersStorable) {
   ast::StructMemberList members{Member("a", ty.i32), Member("b", ty.f32)};
   auto* s = create<ast::Struct>(Source{}, members, ast::StructDecorationList{});
   auto* s_ty = ty.struct_("mystruct", s);
-  EXPECT_TRUE(v()->IsStorable(s_ty));
+  ValidatorImpl& v = Build();
+
+  EXPECT_TRUE(v.IsStorable(s_ty));
 }
 
 TEST_F(ValidatorTest, IsStorable_Struct_SomeMembersNonStorable) {
@@ -757,7 +846,9 @@
   ast::StructMemberList members{Member("a", ty.i32), Member("b", ptr_ty)};
   auto* s = create<ast::Struct>(Source{}, members, ast::StructDecorationList{});
   auto* s_ty = ty.struct_("mystruct", s);
-  EXPECT_FALSE(v()->IsStorable(s_ty));
+  ValidatorImpl& v = Build();
+
+  EXPECT_FALSE(v.IsStorable(s_ty));
 }
 
 }  // namespace
diff --git a/src/validator/validator_test_helper.cc b/src/validator/validator_test_helper.cc
index eb0b903..e1ed61b 100644
--- a/src/validator/validator_test_helper.cc
+++ b/src/validator/validator_test_helper.cc
@@ -20,7 +20,6 @@
 
 ValidatorTestHelper::ValidatorTestHelper() {
   td_ = std::make_unique<TypeDeterminer>(mod);
-  v_ = std::make_unique<ValidatorImpl>(mod);
 }
 
 ValidatorTestHelper::~ValidatorTestHelper() = default;
diff --git a/src/validator/validator_test_helper.h b/src/validator/validator_test_helper.h
index 305f1a4..9500e80 100644
--- a/src/validator/validator_test_helper.h
+++ b/src/validator/validator_test_helper.h
@@ -15,8 +15,10 @@
 #ifndef SRC_VALIDATOR_VALIDATOR_TEST_HELPER_H_
 #define SRC_VALIDATOR_VALIDATOR_TEST_HELPER_H_
 
+#include <functional>
 #include <memory>
 #include <utility>
+#include <vector>
 
 #include "src/ast/builder.h"
 #include "src/type/void_type.h"
@@ -32,9 +34,21 @@
   ValidatorTestHelper();
   ~ValidatorTestHelper() override;
 
-  /// A handle to validator
-  /// @returns a pointer to the validator
-  ValidatorImpl* v() const { return v_.get(); }
+  /// Builds and returns a validator from the module.
+  /// @note The validator is only built once. Multiple calls to Build() will
+  /// return the same ValidatorImpl without rebuilding.
+  /// @return the built validator
+  ValidatorImpl& Build() {
+    if (val_) {
+      return *val_;
+    }
+    val_ = std::make_unique<ValidatorImpl>(mod);
+    for (auto* var : vars_for_testing_) {
+      val_->RegisterVariableForTesting(var);
+    }
+    return *val_;
+  }
+
   /// A handle to type_determiner
   /// @returns a pointer to the type_determiner object
   TypeDeterminer* td() const { return td_.get(); }
@@ -42,13 +56,14 @@
   /// Inserts a variable into the current scope.
   /// @param var the variable to register.
   void RegisterVariable(ast::Variable* var) {
-    v_->RegisterVariableForTesting(var);
+    vars_for_testing_.emplace_back(var);
     td_->RegisterVariableForTesting(var);
   }
 
  private:
-  std::unique_ptr<ValidatorImpl> v_;
   std::unique_ptr<TypeDeterminer> td_;
+  std::unique_ptr<ValidatorImpl> val_;
+  std::vector<ast::Variable*> vars_for_testing_;
 };
 
 }  // namespace tint
diff --git a/src/validator/validator_type_test.cc b/src/validator/validator_type_test.cc
index e199785..b43078c 100644
--- a/src/validator/validator_type_test.cc
+++ b/src/validator/validator_type_test.cc
@@ -52,7 +52,10 @@
   auto* struct_type = ty.struct_("Foo", st);
 
   mod->AddConstructedType(struct_type);
-  EXPECT_TRUE(v()->ValidateConstructedTypes(mod->constructed_types()));
+
+  ValidatorImpl& v = Build();
+
+  EXPECT_TRUE(v.ValidateConstructedTypes(mod->constructed_types()));
 }
 
 TEST_F(ValidatorTypeTest, RuntimeArrayIsLastNoBlock_Fail) {
@@ -69,8 +72,11 @@
 
   auto* struct_type = ty.struct_("Foo", st);
   mod->AddConstructedType(struct_type);
-  EXPECT_FALSE(v()->ValidateConstructedTypes(mod->constructed_types()));
-  EXPECT_EQ(v()->error(),
+
+  ValidatorImpl& v = Build();
+
+  EXPECT_FALSE(v.ValidateConstructedTypes(mod->constructed_types()));
+  EXPECT_EQ(v.error(),
             "v-0031: a struct containing a runtime-sized array must be "
             "in the 'storage' storage class: 'Foo'");
 }
@@ -94,8 +100,11 @@
   auto* struct_type = ty.struct_("Foo", st);
 
   mod->AddConstructedType(struct_type);
-  EXPECT_FALSE(v()->ValidateConstructedTypes(mod->constructed_types()));
-  EXPECT_EQ(v()->error(),
+
+  ValidatorImpl& v = Build();
+
+  EXPECT_FALSE(v.ValidateConstructedTypes(mod->constructed_types()));
+  EXPECT_EQ(v.error(),
             "12:34 v-0015: runtime arrays may only appear as the last member "
             "of a struct");
 }
@@ -117,8 +126,11 @@
 
   auto* struct_type = ty.struct_("s", st);
   mod->AddConstructedType(struct_type);
-  EXPECT_FALSE(v()->ValidateConstructedTypes(mod->constructed_types()));
-  EXPECT_EQ(v()->error(),
+
+  ValidatorImpl& v = Build();
+
+  EXPECT_FALSE(v.ValidateConstructedTypes(mod->constructed_types()));
+  EXPECT_EQ(v.error(),
             "v-0015: runtime arrays may only appear as the last member "
             "of a struct");
 }
@@ -140,7 +152,10 @@
 
   auto* struct_type = ty.struct_("s", st);
   mod->AddConstructedType(struct_type);
-  EXPECT_TRUE(v()->ValidateConstructedTypes(mod->constructed_types()));
+
+  ValidatorImpl& v = Build();
+
+  EXPECT_TRUE(v.ValidateConstructedTypes(mod->constructed_types()));
 }
 
 TEST_F(ValidatorTypeTest, RuntimeArrayInFunction_Fail) {
@@ -160,8 +175,11 @@
   mod->AddFunction(func);
 
   EXPECT_TRUE(td()->Determine()) << td()->error();
-  EXPECT_FALSE(v()->Validate());
-  EXPECT_EQ(v()->error(),
+
+  ValidatorImpl& v = Build();
+
+  EXPECT_FALSE(v.Validate());
+  EXPECT_EQ(v.error(),
             "12:34 v-0015: runtime arrays may only appear as the last member "
             "of a struct");
 }
@@ -192,8 +210,11 @@
   mod->AddFunction(main);
 
   EXPECT_TRUE(td()->Determine()) << td()->error();
-  EXPECT_FALSE(v()->Validate());
-  EXPECT_EQ(v()->error(),
+
+  ValidatorImpl& v = Build();
+
+  EXPECT_FALSE(v.Validate());
+  EXPECT_EQ(v.error(),
             "12:34 v-0015: runtime arrays may only appear as the last member "
             "of a struct");
 }
diff --git a/src/writer/hlsl/generator_impl_alias_type_test.cc b/src/writer/hlsl/generator_impl_alias_type_test.cc
index e04d641..04a4f8b 100644
--- a/src/writer/hlsl/generator_impl_alias_type_test.cc
+++ b/src/writer/hlsl/generator_impl_alias_type_test.cc
@@ -29,6 +29,8 @@
 TEST_F(HlslGeneratorImplTest_Alias, EmitAlias_F32) {
   auto* alias = ty.alias("a", ty.f32);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitConstructedType(out, alias)) << gen.error();
   EXPECT_EQ(result(), R"(typedef float a;
 )");
@@ -37,6 +39,8 @@
 TEST_F(HlslGeneratorImplTest_Alias, EmitAlias_NameCollision) {
   auto* alias = ty.alias("float", ty.f32);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitConstructedType(out, alias)) << gen.error();
   EXPECT_EQ(result(), R"(typedef float float_tint_0;
 )");
@@ -51,6 +55,8 @@
   auto* s = ty.struct_("A", str);
   auto* alias = ty.alias("B", s);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitConstructedType(out, alias)) << gen.error();
   EXPECT_EQ(result(), R"(struct B {
   float a;
diff --git a/src/writer/hlsl/generator_impl_array_accessor_test.cc b/src/writer/hlsl/generator_impl_array_accessor_test.cc
index cb65569..79cf085 100644
--- a/src/writer/hlsl/generator_impl_array_accessor_test.cc
+++ b/src/writer/hlsl/generator_impl_array_accessor_test.cc
@@ -32,6 +32,8 @@
 TEST_F(HlslGeneratorImplTest_Expression, EmitExpression_ArrayAccessor) {
   auto* expr = IndexAccessor("ary", 5);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitExpression(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(), "ary[5]");
 }
@@ -39,6 +41,8 @@
 TEST_F(HlslGeneratorImplTest_Expression, EmitArrayAccessor) {
   auto* expr = IndexAccessor("ary", "idx");
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitExpression(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(), "ary[idx]");
 }
diff --git a/src/writer/hlsl/generator_impl_assign_test.cc b/src/writer/hlsl/generator_impl_assign_test.cc
index 549ce5e..c44681c 100644
--- a/src/writer/hlsl/generator_impl_assign_test.cc
+++ b/src/writer/hlsl/generator_impl_assign_test.cc
@@ -32,6 +32,8 @@
   auto* rhs = Expr("rhs");
   auto* assign = create<ast::AssignmentStatement>(lhs, rhs);
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(out, assign)) << gen.error();
diff --git a/src/writer/hlsl/generator_impl_binary_test.cc b/src/writer/hlsl/generator_impl_binary_test.cc
index 3240c10..1786684 100644
--- a/src/writer/hlsl/generator_impl_binary_test.cc
+++ b/src/writer/hlsl/generator_impl_binary_test.cc
@@ -72,6 +72,9 @@
   auto* expr = create<ast::BinaryExpression>(params.op, left, right);
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitExpression(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(), params.result);
 }
@@ -90,6 +93,9 @@
   auto* expr = create<ast::BinaryExpression>(params.op, left, right);
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitExpression(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(), params.result);
 }
@@ -108,6 +114,9 @@
   auto* expr = create<ast::BinaryExpression>(params.op, left, right);
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitExpression(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(), params.result);
 }
@@ -140,6 +149,9 @@
       create<ast::BinaryExpression>(ast::BinaryOp::kMultiply, lhs, rhs);
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
+
+  GeneratorImpl& gen = Build();
+
   EXPECT_TRUE(gen.EmitExpression(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(),
             "(float3(1.0f, 1.0f, 1.0f) * "
@@ -154,6 +166,9 @@
       create<ast::BinaryExpression>(ast::BinaryOp::kMultiply, lhs, rhs);
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
+
+  GeneratorImpl& gen = Build();
+
   EXPECT_TRUE(gen.EmitExpression(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(),
             "(1.0f * float3(1.0f, 1.0f, "
@@ -171,6 +186,9 @@
       create<ast::BinaryExpression>(ast::BinaryOp::kMultiply, lhs, rhs);
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
+
+  GeneratorImpl& gen = Build();
+
   EXPECT_TRUE(gen.EmitExpression(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(), "(mat * 1.0f)");
 }
@@ -186,6 +204,9 @@
       create<ast::BinaryExpression>(ast::BinaryOp::kMultiply, lhs, rhs);
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
+
+  GeneratorImpl& gen = Build();
+
   EXPECT_TRUE(gen.EmitExpression(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(), "(1.0f * mat)");
 }
@@ -201,6 +222,9 @@
       create<ast::BinaryExpression>(ast::BinaryOp::kMultiply, lhs, rhs);
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
+
+  GeneratorImpl& gen = Build();
+
   EXPECT_TRUE(gen.EmitExpression(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(), "mul(mat, float3(1.0f, 1.0f, 1.0f))");
 }
@@ -216,6 +240,9 @@
       create<ast::BinaryExpression>(ast::BinaryOp::kMultiply, lhs, rhs);
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
+
+  GeneratorImpl& gen = Build();
+
   EXPECT_TRUE(gen.EmitExpression(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(), "mul(float3(1.0f, 1.0f, 1.0f), mat)");
 }
@@ -231,6 +258,9 @@
       create<ast::BinaryExpression>(ast::BinaryOp::kMultiply, lhs, rhs);
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
+
+  GeneratorImpl& gen = Build();
+
   EXPECT_TRUE(gen.EmitExpression(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(), "mul(mat, mat)");
 }
@@ -242,6 +272,8 @@
   auto* expr =
       create<ast::BinaryExpression>(ast::BinaryOp::kLogicalAnd, left, right);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitExpression(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(), "(_tint_tmp)");
   EXPECT_EQ(pre_result(), R"(bool _tint_tmp = left;
@@ -263,6 +295,8 @@
       create<ast::BinaryExpression>(ast::BinaryOp::kLogicalAnd, a, b),
       create<ast::BinaryExpression>(ast::BinaryOp::kLogicalOr, c, d));
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitExpression(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(), "(_tint_tmp_0)");
   EXPECT_EQ(pre_result(), R"(bool _tint_tmp = a;
@@ -287,6 +321,8 @@
   auto* expr =
       create<ast::BinaryExpression>(ast::BinaryOp::kLogicalOr, left, right);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitExpression(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(), "(_tint_tmp)");
   EXPECT_EQ(pre_result(), R"(bool _tint_tmp = left;
@@ -331,6 +367,8 @@
           else_stmt,
       });
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitStatement(out, expr)) << gen.error();
   EXPECT_EQ(result(), R"(bool _tint_tmp = a;
 if (_tint_tmp) {
@@ -362,6 +400,8 @@
       ast::BinaryOp::kLogicalOr,
       create<ast::BinaryExpression>(ast::BinaryOp::kLogicalAnd, a, b), c));
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitStatement(out, expr)) << gen.error();
   EXPECT_EQ(result(), R"(bool _tint_tmp = a;
 if (_tint_tmp) {
@@ -388,6 +428,8 @@
           ast::BinaryOp::kLogicalAnd,
           create<ast::BinaryExpression>(ast::BinaryOp::kLogicalOr, b, c), d));
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitStatement(out, expr)) << gen.error();
   EXPECT_EQ(result(), R"(bool _tint_tmp = b;
 if (!_tint_tmp) {
@@ -417,6 +459,8 @@
 
   auto* expr = create<ast::VariableDeclStatement>(var);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitStatement(out, expr)) << gen.error();
   EXPECT_EQ(result(), R"(bool _tint_tmp = b;
 if (_tint_tmp) {
@@ -443,6 +487,8 @@
           ast::BinaryOp::kLogicalAnd, a,
           create<ast::BinaryExpression>(ast::BinaryOp::kLogicalOr, b, c)));
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitExpression(pre, out, expr)) << gen.error();
   EXPECT_EQ(pre_result(), R"(bool _tint_tmp = a;
 if (_tint_tmp) {
@@ -477,6 +523,8 @@
 
   auto* expr = create<ast::CallStatement>(Call("foo", params));
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitStatement(out, expr)) << gen.error();
   EXPECT_EQ(result(), R"(bool _tint_tmp = a;
 if (_tint_tmp) {
diff --git a/src/writer/hlsl/generator_impl_bitcast_test.cc b/src/writer/hlsl/generator_impl_bitcast_test.cc
index a6fc904..f4c9f39 100644
--- a/src/writer/hlsl/generator_impl_bitcast_test.cc
+++ b/src/writer/hlsl/generator_impl_bitcast_test.cc
@@ -33,6 +33,8 @@
   auto* id = Expr("id");
   auto* bitcast = create<ast::BitcastExpression>(ty.f32, id);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitExpression(pre, out, bitcast)) << gen.error();
   EXPECT_EQ(result(), "asfloat(id)");
 }
@@ -41,6 +43,8 @@
   auto* id = Expr("id");
   auto* bitcast = create<ast::BitcastExpression>(ty.i32, id);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitExpression(pre, out, bitcast)) << gen.error();
   EXPECT_EQ(result(), "asint(id)");
 }
@@ -49,6 +53,8 @@
   auto* id = Expr("id");
   auto* bitcast = create<ast::BitcastExpression>(ty.u32, id);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitExpression(pre, out, bitcast)) << gen.error();
   EXPECT_EQ(result(), "asuint(id)");
 }
diff --git a/src/writer/hlsl/generator_impl_block_test.cc b/src/writer/hlsl/generator_impl_block_test.cc
index 304fe12..edb9be2 100644
--- a/src/writer/hlsl/generator_impl_block_test.cc
+++ b/src/writer/hlsl/generator_impl_block_test.cc
@@ -29,6 +29,9 @@
   auto* b = create<ast::BlockStatement>(ast::StatementList{
       create<ast::DiscardStatement>(),
   });
+
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(out, b)) << gen.error();
@@ -42,6 +45,9 @@
   auto* b = create<ast::BlockStatement>(ast::StatementList{
       create<ast::DiscardStatement>(),
   });
+
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitBlock(out, b)) << gen.error();
diff --git a/src/writer/hlsl/generator_impl_break_test.cc b/src/writer/hlsl/generator_impl_break_test.cc
index 54d26b8..e7b865c 100644
--- a/src/writer/hlsl/generator_impl_break_test.cc
+++ b/src/writer/hlsl/generator_impl_break_test.cc
@@ -29,6 +29,8 @@
 TEST_F(HlslGeneratorImplTest_Break, Emit_Break) {
   auto* b = create<ast::BreakStatement>();
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(out, b)) << gen.error();
diff --git a/src/writer/hlsl/generator_impl_call_test.cc b/src/writer/hlsl/generator_impl_call_test.cc
index 92b1905..23b2176 100644
--- a/src/writer/hlsl/generator_impl_call_test.cc
+++ b/src/writer/hlsl/generator_impl_call_test.cc
@@ -36,6 +36,8 @@
                     ast::StatementList{}, ast::FunctionDecorationList{});
   mod->AddFunction(func);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitExpression(pre, out, call)) << gen.error();
   EXPECT_EQ(result(), "my_func()");
 }
@@ -47,6 +49,8 @@
                     ast::StatementList{}, ast::FunctionDecorationList{});
   mod->AddFunction(func);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitExpression(pre, out, call)) << gen.error();
   EXPECT_EQ(result(), "my_func(param1, param2)");
 }
@@ -57,6 +61,9 @@
   auto* func = Func("my_func", ast::VariableList{}, ty.void_,
                     ast::StatementList{}, ast::FunctionDecorationList{});
   mod->AddFunction(func);
+
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
   ASSERT_TRUE(gen.EmitStatement(out, call)) << gen.error();
   EXPECT_EQ(result(), "  my_func(param1, param2);\n");
diff --git a/src/writer/hlsl/generator_impl_case_test.cc b/src/writer/hlsl/generator_impl_case_test.cc
index d6fd895..b60e7e5 100644
--- a/src/writer/hlsl/generator_impl_case_test.cc
+++ b/src/writer/hlsl/generator_impl_case_test.cc
@@ -38,6 +38,8 @@
   lit.push_back(Literal(5));
   auto* c = create<ast::CaseStatement>(lit, body);
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitCase(out, c)) << gen.error();
@@ -53,6 +55,8 @@
   auto* c = create<ast::CaseStatement>(
       lit, create<ast::BlockStatement>(ast::StatementList{}));
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitCase(out, c)) << gen.error();
@@ -70,6 +74,8 @@
   lit.push_back(Literal(5));
   auto* c = create<ast::CaseStatement>(lit, body);
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitCase(out, c)) << gen.error();
@@ -88,6 +94,8 @@
   lit.push_back(Literal(6));
   auto* c = create<ast::CaseStatement>(lit, body);
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitCase(out, c)) << gen.error();
@@ -104,6 +112,8 @@
   });
   auto* c = create<ast::CaseStatement>(ast::CaseSelectorList{}, body);
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitCase(out, c)) << gen.error();
diff --git a/src/writer/hlsl/generator_impl_cast_test.cc b/src/writer/hlsl/generator_impl_cast_test.cc
index 6a8c533..de0d39f 100644
--- a/src/writer/hlsl/generator_impl_cast_test.cc
+++ b/src/writer/hlsl/generator_impl_cast_test.cc
@@ -30,12 +30,18 @@
 
 TEST_F(HlslGeneratorImplTest_Cast, EmitExpression_Cast_Scalar) {
   auto* cast = Construct<f32>("id");
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitExpression(pre, out, cast)) << gen.error();
   EXPECT_EQ(result(), "float(id)");
 }
 
 TEST_F(HlslGeneratorImplTest_Cast, EmitExpression_Cast_Vector) {
   auto* cast = vec3<f32>("id");
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitExpression(pre, out, cast)) << gen.error();
   EXPECT_EQ(result(), "float3(id)");
 }
diff --git a/src/writer/hlsl/generator_impl_constructor_test.cc b/src/writer/hlsl/generator_impl_constructor_test.cc
index 0eaeb36..071d240 100644
--- a/src/writer/hlsl/generator_impl_constructor_test.cc
+++ b/src/writer/hlsl/generator_impl_constructor_test.cc
@@ -38,6 +38,8 @@
 TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Bool) {
   auto* expr = Expr(false);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitConstructor(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(), "false");
 }
@@ -45,6 +47,8 @@
 TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Int) {
   auto* expr = Expr(-12345);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitConstructor(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(), "-12345");
 }
@@ -52,6 +56,8 @@
 TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_UInt) {
   auto* expr = Expr(56779u);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitConstructor(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(), "56779u");
 }
@@ -60,6 +66,8 @@
   // Use a number close to 1<<30 but whose decimal representation ends in 0.
   auto* expr = Expr(static_cast<float>((1 << 30) - 4));
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitConstructor(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(), "1073741824.0f");
 }
@@ -67,6 +75,8 @@
 TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Float) {
   auto* expr = Construct<f32>(-1.2e-5f);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitConstructor(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(), "float(-0.000012f)");
 }
@@ -74,6 +84,8 @@
 TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Bool) {
   auto* expr = Construct<bool>(true);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitConstructor(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(), "bool(true)");
 }
@@ -81,6 +93,8 @@
 TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Int) {
   auto* expr = Construct<i32>(-12345);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitConstructor(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(), "int(-12345)");
 }
@@ -88,6 +102,8 @@
 TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Uint) {
   auto* expr = Construct<u32>(12345u);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitConstructor(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(), "uint(12345u)");
 }
@@ -95,6 +111,8 @@
 TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Vec) {
   auto* expr = vec3<f32>(1.f, 2.f, 3.f);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitConstructor(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(), "float3(1.0f, 2.0f, 3.0f)");
 }
@@ -102,6 +120,8 @@
 TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Vec_Empty) {
   auto* expr = vec3<f32>();
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitConstructor(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(), "float3(0.0f)");
 }
@@ -112,6 +132,8 @@
 
   auto* expr = mat2x3<f32>(vec3<f32>(1.f, 2.f, 3.f), vec3<f32>(3.f, 4.f, 5.f));
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitConstructor(pre, out, expr)) << gen.error();
 
   // A matrix of type T with n columns and m rows can also be constructed from
@@ -124,6 +146,8 @@
   auto* expr = Construct(ty.array(ty.vec3<f32>(), 3), vec3<f32>(1.f, 2.f, 3.f),
                          vec3<f32>(4.f, 5.f, 6.f), vec3<f32>(7.f, 8.f, 9.f));
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitConstructor(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(),
             "{float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f),"
diff --git a/src/writer/hlsl/generator_impl_continue_test.cc b/src/writer/hlsl/generator_impl_continue_test.cc
index 7e7aec4..f87de21 100644
--- a/src/writer/hlsl/generator_impl_continue_test.cc
+++ b/src/writer/hlsl/generator_impl_continue_test.cc
@@ -29,6 +29,8 @@
 TEST_F(HlslGeneratorImplTest_Continue, Emit_Continue) {
   auto* c = create<ast::ContinueStatement>();
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(out, c)) << gen.error();
diff --git a/src/writer/hlsl/generator_impl_discard_test.cc b/src/writer/hlsl/generator_impl_discard_test.cc
index cd96c69..9d0c425 100644
--- a/src/writer/hlsl/generator_impl_discard_test.cc
+++ b/src/writer/hlsl/generator_impl_discard_test.cc
@@ -26,6 +26,8 @@
 TEST_F(HlslGeneratorImplTest_Discard, Emit_Discard) {
   auto* stmt = create<ast::DiscardStatement>();
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(out, stmt)) << gen.error();
diff --git a/src/writer/hlsl/generator_impl_function_entry_point_data_test.cc b/src/writer/hlsl/generator_impl_function_entry_point_data_test.cc
index ae627c8..3f4e9ee 100644
--- a/src/writer/hlsl/generator_impl_function_entry_point_data_test.cc
+++ b/src/writer/hlsl/generator_impl_function_entry_point_data_test.cc
@@ -75,6 +75,9 @@
   std::unordered_set<Symbol> globals;
 
   ASSERT_TRUE(td.Determine()) << td.error();
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitEntryPointData(out, func, globals)) << gen.error();
   EXPECT_EQ(result(), R"(struct vtx_main_in {
   float foo : TEXCOORD0;
@@ -125,6 +128,9 @@
   std::unordered_set<Symbol> globals;
 
   ASSERT_TRUE(td.Determine()) << td.error();
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitEntryPointData(out, func, globals)) << gen.error();
   EXPECT_EQ(result(), R"(struct vtx_main_out {
   float foo : TEXCOORD0;
@@ -175,6 +181,9 @@
   std::unordered_set<Symbol> globals;
 
   ASSERT_TRUE(td.Determine()) << td.error();
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitEntryPointData(out, func, globals)) << gen.error();
   EXPECT_EQ(result(), R"(struct main_in {
   float foo : TEXCOORD0;
@@ -225,6 +234,9 @@
   std::unordered_set<Symbol> globals;
 
   ASSERT_TRUE(td.Determine()) << td.error();
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitEntryPointData(out, func, globals)) << gen.error();
   EXPECT_EQ(result(), R"(struct main_out {
   float foo : SV_Target0;
@@ -272,6 +284,9 @@
   std::unordered_set<Symbol> globals;
 
   ASSERT_TRUE(td.Determine()) << td.error();
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_FALSE(gen.EmitEntryPointData(out, func, globals)) << gen.error();
   EXPECT_EQ(gen.error(), R"(invalid location variable for pipeline stage)");
 }
@@ -314,6 +329,9 @@
   std::unordered_set<Symbol> globals;
 
   ASSERT_TRUE(td.Determine()) << td.error();
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_FALSE(gen.EmitEntryPointData(out, func, globals)) << gen.error();
   EXPECT_EQ(gen.error(), R"(invalid location variable for pipeline stage)");
 }
@@ -364,6 +382,9 @@
   std::unordered_set<Symbol> globals;
 
   ASSERT_TRUE(td.Determine()) << td.error();
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitEntryPointData(out, func, globals)) << gen.error();
   EXPECT_EQ(result(), R"(struct main_in {
   float4 coord : SV_Position;
diff --git a/src/writer/hlsl/generator_impl_function_test.cc b/src/writer/hlsl/generator_impl_function_test.cc
index ee5e40b..e5a8570 100644
--- a/src/writer/hlsl/generator_impl_function_test.cc
+++ b/src/writer/hlsl/generator_impl_function_test.cc
@@ -60,6 +60,9 @@
                     ast::FunctionDecorationList{});
 
   mod->AddFunction(func);
+
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.Generate(out)) << gen.error();
@@ -78,6 +81,9 @@
                     ast::FunctionDecorationList{});
 
   mod->AddFunction(func);
+
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.Generate(out)) << gen.error();
@@ -100,6 +106,9 @@
            ast::FunctionDecorationList{});
 
   mod->AddFunction(func);
+
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.Generate(out)) << gen.error();
@@ -122,6 +131,9 @@
   mod->AddFunction(func);
 
   ASSERT_TRUE(td.Determine()) << td.error();
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.Generate(out)) << gen.error();
   EXPECT_EQ(result(), R"(void main() {
   return;
@@ -160,6 +172,9 @@
   mod->AddFunction(func);
 
   ASSERT_TRUE(td.Determine()) << td.error();
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.Generate(out)) << gen.error();
   EXPECT_EQ(result(), R"(struct main_in {
   float foo : TEXCOORD0;
@@ -209,6 +224,9 @@
   mod->AddFunction(func);
 
   ASSERT_TRUE(td.Determine()) << td.error();
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.Generate(out)) << gen.error();
   EXPECT_EQ(result(), R"(struct frag_main_in {
   float foo : TEXCOORD0;
@@ -261,6 +279,9 @@
   mod->AddFunction(func);
 
   ASSERT_TRUE(td.Determine()) << td.error();
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.Generate(out)) << gen.error();
   EXPECT_EQ(result(), R"(struct frag_main_in {
   float4 coord : SV_Position;
@@ -307,6 +328,9 @@
   mod->AddFunction(func);
 
   ASSERT_TRUE(td.Determine()) << td.error();
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.Generate(out)) << gen.error();
   EXPECT_EQ(result(), R"(cbuffer cbuffer_coord : register(b0) {
   float4 coord;
@@ -357,6 +381,9 @@
   mod->AddFunction(func);
 
   ASSERT_TRUE(td.Determine()) << td.error();
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.Generate(out)) << gen.error();
   EXPECT_EQ(result(), R"(struct Uniforms {
   float4 coord;
@@ -407,6 +434,9 @@
   mod->AddFunction(func);
 
   ASSERT_TRUE(td.Determine()) << td.error();
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.Generate(out)) << gen.error();
   EXPECT_EQ(result(), R"(RWByteAddressBuffer coord : register(u0);
 
@@ -454,6 +484,9 @@
   mod->AddFunction(func);
 
   ASSERT_TRUE(td.Determine()) << td.error();
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.Generate(out)) << gen.error();
   EXPECT_EQ(result(), R"(ByteAddressBuffer coord : register(u0);
 
@@ -498,6 +531,9 @@
   mod->AddFunction(func);
 
   ASSERT_TRUE(td.Determine()) << td.error();
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.Generate(out)) << gen.error();
   EXPECT_EQ(result(), R"(RWByteAddressBuffer coord : register(u0);
 
@@ -512,7 +548,6 @@
 TEST_F(
     HlslGeneratorImplTest_Function,
     Emit_FunctionDecoration_Called_By_EntryPoints_WithLocationGlobals_And_Params) {  // NOLINT
-
   auto* foo_var = Var("foo", ast::StorageClass::kInput, ty.f32, nullptr,
                       ast::VariableDecorationList{
                           create<ast::LocationDecoration>(0),
@@ -562,6 +597,9 @@
   mod->AddFunction(func_1);
 
   ASSERT_TRUE(td.Determine()) << td.error();
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.Generate(out)) << gen.error();
   EXPECT_EQ(result(), R"(struct ep_1_in {
   float foo : TEXCOORD0;
@@ -624,6 +662,9 @@
   mod->AddFunction(func_1);
 
   ASSERT_TRUE(td.Determine()) << td.error();
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.Generate(out)) << gen.error();
   EXPECT_EQ(result(), R"(struct ep_1_out {
   float depth : SV_Depth;
@@ -645,7 +686,6 @@
 TEST_F(
     HlslGeneratorImplTest_Function,
     Emit_FunctionDecoration_Called_By_EntryPoints_WithBuiltinGlobals_And_Params) {  // NOLINT
-
   auto* coord_var =
       Var("coord", ast::StorageClass::kInput, ty.vec4<f32>(), nullptr,
           ast::VariableDecorationList{
@@ -691,6 +731,9 @@
   mod->AddFunction(func_1);
 
   ASSERT_TRUE(td.Determine()) << td.error();
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.Generate(out)) << gen.error();
   EXPECT_EQ(result(), R"(struct ep_1_in {
   float4 coord : SV_Position;
@@ -754,6 +797,9 @@
   mod->AddFunction(func);
 
   ASSERT_TRUE(td.Determine()) << td.error();
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.Generate(out)) << gen.error();
   EXPECT_EQ(result(), R"(cbuffer cbuffer_coord : register(b0) {
   float4 coord;
@@ -811,6 +857,9 @@
   mod->AddFunction(func);
 
   ASSERT_TRUE(td.Determine()) << td.error();
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.Generate(out)) << gen.error();
   EXPECT_EQ(result(), R"(RWByteAddressBuffer coord : register(u0);
 
@@ -856,6 +905,9 @@
   mod->AddFunction(func_1);
 
   ASSERT_TRUE(td.Determine()) << td.error();
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.Generate(out)) << gen.error();
   EXPECT_EQ(result(), R"(struct ep_1_out {
   float bar : SV_Target1;
@@ -883,6 +935,8 @@
 
   mod->AddFunction(func);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.Generate(out)) << gen.error();
   EXPECT_EQ(result(), R"(void GeometryShader_tint_0() {
   return;
@@ -905,6 +959,9 @@
   mod->AddFunction(func);
 
   ASSERT_TRUE(td.Determine()) << td.error();
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.Generate(out)) << gen.error();
   EXPECT_EQ(result(), R"([numthreads(1, 1, 1)]
 void main() {
@@ -929,6 +986,9 @@
   mod->AddFunction(func);
 
   ASSERT_TRUE(td.Determine()) << td.error();
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.Generate(out)) << gen.error();
   EXPECT_EQ(result(), R"([numthreads(2, 4, 6)]
 void main() {
@@ -949,6 +1009,9 @@
       ast::FunctionDecorationList{});
 
   mod->AddFunction(func);
+
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.Generate(out)) << gen.error();
@@ -1029,6 +1092,8 @@
   }
 
   ASSERT_TRUE(td.Determine()) << td.error();
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.Generate(out)) << gen.error();
   EXPECT_EQ(result(), R"(struct Data {
   float d;
diff --git a/src/writer/hlsl/generator_impl_identifier_test.cc b/src/writer/hlsl/generator_impl_identifier_test.cc
index eba1c18..eaaebc1 100644
--- a/src/writer/hlsl/generator_impl_identifier_test.cc
+++ b/src/writer/hlsl/generator_impl_identifier_test.cc
@@ -25,6 +25,9 @@
 
 TEST_F(HlslGeneratorImplTest_Identifier, EmitIdentifierExpression) {
   auto* i = Expr("foo");
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitExpression(pre, out, i)) << gen.error();
   EXPECT_EQ(result(), "foo");
 }
@@ -32,6 +35,9 @@
 TEST_F(HlslGeneratorImplTest_Identifier,
        EmitIdentifierExpression_Single_WithCollision) {
   auto* i = Expr("virtual");
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitExpression(pre, out, i)) << gen.error();
   EXPECT_EQ(result(), "virtual_tint_0");
 }
diff --git a/src/writer/hlsl/generator_impl_if_test.cc b/src/writer/hlsl/generator_impl_if_test.cc
index 3825a10..1e67070 100644
--- a/src/writer/hlsl/generator_impl_if_test.cc
+++ b/src/writer/hlsl/generator_impl_if_test.cc
@@ -32,8 +32,10 @@
       create<ast::ReturnStatement>(),
   });
   auto* i = create<ast::IfStatement>(cond, body, ast::ElseStatementList{});
-  gen.increment_indent();
 
+  GeneratorImpl& gen = Build();
+
+  gen.increment_indent();
   ASSERT_TRUE(gen.EmitStatement(out, i)) << gen.error();
   EXPECT_EQ(result(), R"(  if (cond) {
     return;
@@ -55,6 +57,8 @@
       cond, body,
       ast::ElseStatementList{create<ast::ElseStatement>(else_cond, else_body)});
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(out, i)) << gen.error();
@@ -81,6 +85,8 @@
       cond, body,
       ast::ElseStatementList{create<ast::ElseStatement>(nullptr, else_body)});
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(out, i)) << gen.error();
@@ -114,6 +120,8 @@
           create<ast::ElseStatement>(nullptr, else_body_2),
       });
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(out, i)) << gen.error();
diff --git a/src/writer/hlsl/generator_impl_import_test.cc b/src/writer/hlsl/generator_impl_import_test.cc
index 8b68fcc..8613a0d 100644
--- a/src/writer/hlsl/generator_impl_import_test.cc
+++ b/src/writer/hlsl/generator_impl_import_test.cc
@@ -54,6 +54,9 @@
   auto* expr = Call(ident, 1.f);
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitCall(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(), std::string(param.hlsl_name) + "(1.0f)");
 }
@@ -92,6 +95,9 @@
   auto* expr = Call(param.name, Expr(1));
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitCall(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(), std::string(param.hlsl_name) + "(1)");
 }
@@ -106,6 +112,9 @@
   auto* expr = Call(param.name, 1.f, 2.f);
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitCall(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(), std::string(param.hlsl_name) + "(1.0f, 2.0f)");
 }
@@ -127,6 +136,9 @@
       Call(param.name, vec3<f32>(1.f, 2.f, 3.f), vec3<f32>(4.f, 5.f, 6.f));
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitCall(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(),
             std::string(param.hlsl_name) +
@@ -143,6 +155,9 @@
   auto* expr = Call(param.name, 1, 2);
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitCall(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(), std::string(param.hlsl_name) + "(1, 2)");
 }
@@ -158,6 +173,9 @@
   auto* expr = Call(param.name, 1.f, 2.f, 3.f);
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitCall(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(), std::string(param.hlsl_name) + "(1.0f, 2.0f, 3.0f)");
 }
@@ -180,6 +198,9 @@
   auto* expr = Call(param.name, 1, 2, 3);
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitCall(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(), std::string(param.hlsl_name) + "(1, 2, 3)");
 }
@@ -197,6 +218,9 @@
   // Register the global
   ASSERT_TRUE(td.Determine()) << td.error();
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitCall(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(), std::string("determinant(var)"));
 }
diff --git a/src/writer/hlsl/generator_impl_intrinsic_test.cc b/src/writer/hlsl/generator_impl_intrinsic_test.cc
index 79000d5..a3b0a71 100644
--- a/src/writer/hlsl/generator_impl_intrinsic_test.cc
+++ b/src/writer/hlsl/generator_impl_intrinsic_test.cc
@@ -38,6 +38,9 @@
 using HlslIntrinsicTest = TestParamHelper<IntrinsicData>;
 TEST_P(HlslIntrinsicTest, Emit) {
   auto param = GetParam();
+
+  GeneratorImpl& gen = Build();
+
   EXPECT_EQ(gen.generate_intrinsic_name(param.intrinsic), param.hlsl_name);
 }
 INSTANTIATE_TEST_SUITE_P(
@@ -71,6 +74,8 @@
 }
 
 TEST_F(HlslGeneratorImplTest_Intrinsic, Intrinsic_Bad_Name) {
+  GeneratorImpl& gen = Build();
+
   EXPECT_EQ(gen.generate_intrinsic_name(ast::Intrinsic::kNone), "");
 }
 
@@ -85,6 +90,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(call)) << td.error();
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
   ASSERT_TRUE(gen.EmitExpression(pre, out, call)) << gen.error();
   EXPECT_EQ(result(), "  dot(param1, param2)");
diff --git a/src/writer/hlsl/generator_impl_intrinsic_texture_test.cc b/src/writer/hlsl/generator_impl_intrinsic_texture_test.cc
index 30fab52..a0194ec 100644
--- a/src/writer/hlsl/generator_impl_intrinsic_texture_test.cc
+++ b/src/writer/hlsl/generator_impl_intrinsic_texture_test.cc
@@ -22,6 +22,7 @@
 #include "src/type/sampled_texture_type.h"
 #include "src/type_determiner.h"
 #include "src/writer/hlsl/generator_impl.h"
+#include "src/writer/hlsl/test_helper.h"
 
 namespace tint {
 namespace writer {
@@ -404,26 +405,11 @@
 }  // NOLINT - Ignore the length of this function
 
 class HlslGeneratorIntrinsicTextureTest
-    : public ast::BuilderWithModule,
-      public testing::TestWithParam<ast::intrinsic::test::TextureOverloadCase> {
+    : public TestParamHelper<ast::intrinsic::test::TextureOverloadCase> {
  protected:
   void OnVariableBuilt(ast::Variable* var) override {
     td.RegisterVariableForTesting(var);
   }
-
-  /// @returns the result string
-  std::string result() const { return out.str(); }
-  /// @returns the pre result string
-  std::string pre_result() const { return pre.str(); }
-
-  /// The type determiner
-  TypeDeterminer td{mod};
-  /// The generator
-  GeneratorImpl gen{mod};
-  /// The output stream
-  std::ostringstream out;
-  /// The pre-output stream
-  std::ostringstream pre;
 };
 
 TEST_P(HlslGeneratorIntrinsicTextureTest, Call) {
@@ -437,6 +423,8 @@
   ASSERT_TRUE(td.Determine()) << td.error();
   ASSERT_TRUE(td.DetermineResultType(call)) << td.error();
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitExpression(pre, out, call)) << gen.error();
 
   auto expected = expected_texture_overload(param.overload);
diff --git a/src/writer/hlsl/generator_impl_loop_test.cc b/src/writer/hlsl/generator_impl_loop_test.cc
index 100e21d..09befb2 100644
--- a/src/writer/hlsl/generator_impl_loop_test.cc
+++ b/src/writer/hlsl/generator_impl_loop_test.cc
@@ -38,6 +38,9 @@
       create<ast::DiscardStatement>(),
   });
   auto* l = create<ast::LoopStatement>(body, nullptr);
+
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(out, l)) << gen.error();
@@ -55,6 +58,9 @@
       create<ast::ReturnStatement>(),
   });
   auto* l = create<ast::LoopStatement>(body, continuing);
+
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(out, l)) << gen.error();
@@ -93,6 +99,9 @@
   });
 
   auto* outer = create<ast::LoopStatement>(body, continuing);
+
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(out, outer)) << gen.error();
@@ -158,6 +167,9 @@
       create<ast::AssignmentStatement>(lhs, rhs),
   });
   auto* outer = create<ast::LoopStatement>(body, continuing);
+
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(out, outer)) << gen.error();
diff --git a/src/writer/hlsl/generator_impl_member_accessor_test.cc b/src/writer/hlsl/generator_impl_member_accessor_test.cc
index 3121135..e1ade73 100644
--- a/src/writer/hlsl/generator_impl_member_accessor_test.cc
+++ b/src/writer/hlsl/generator_impl_member_accessor_test.cc
@@ -46,13 +46,17 @@
 
   auto* s = ty.struct_("Str", strct);
   auto* str_var = Var("str", ast::StorageClass::kPrivate, s);
+  mod->AddGlobalVariable(str_var);
+
   auto* expr = MemberAccessor("str", "mem");
 
   td.RegisterVariableForTesting(str_var);
-  gen.register_global(str_var);
-  mod->AddGlobalVariable(str_var);
-
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
+
+  GeneratorImpl& gen = Build();
+
+  gen.register_global(str_var);
+
   ASSERT_TRUE(gen.EmitExpression(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(), "str.mem");
 }
@@ -75,15 +79,18 @@
 
   auto* s = ty.struct_("Data", str);
   auto* coord_var = Var("data", ast::StorageClass::kStorage, s);
-  auto* expr = MemberAccessor("data", "b");
-
-  td.RegisterVariableForTesting(coord_var);
-  gen.register_global(coord_var);
   mod->AddGlobalVariable(coord_var);
+  td.RegisterVariableForTesting(coord_var);
+
+  auto* expr = MemberAccessor("data", "b");
 
   ASSERT_TRUE(td.Determine()) << td.error();
   ASSERT_TRUE(td.DetermineResultType(expr));
 
+  GeneratorImpl& gen = Build();
+
+  gen.register_global(coord_var);
+
   ASSERT_TRUE(gen.EmitExpression(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(), "asfloat(data.Load(4))");
 }
@@ -105,18 +112,22 @@
       ast::StructDecorationList{});
   auto* s = ty.struct_("Data", str);
   auto* coord_var = Var("data", ast::StorageClass::kStorage, s);
-  auto* expr = MemberAccessor("data", "a");
-
-  td.RegisterVariableForTesting(coord_var);
-  gen.register_global(coord_var);
   mod->AddGlobalVariable(coord_var);
+  td.RegisterVariableForTesting(coord_var);
+
+  auto* expr = MemberAccessor("data", "a");
 
   ASSERT_TRUE(td.Determine()) << td.error();
   ASSERT_TRUE(td.DetermineResultType(expr));
 
+  GeneratorImpl& gen = Build();
+
+  gen.register_global(coord_var);
+
   ASSERT_TRUE(gen.EmitExpression(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(), "asint(data.Load(0))");
 }
+
 TEST_F(HlslGeneratorImplTest_MemberAccessor,
        EmitExpression_MemberAccessor_StorageBuffer_Store_Matrix) {
   // struct Data {
@@ -138,7 +149,9 @@
 
   auto* s = ty.struct_("Data", str);
   auto* b_var = Var("b", ast::StorageClass::kPrivate, ty.mat2x3<f32>());
+  mod->AddGlobalVariable(b_var);
   auto* coord_var = Var("data", ast::StorageClass::kStorage, s);
+  mod->AddGlobalVariable(coord_var);
 
   auto* lhs = MemberAccessor("data", "a");
   auto* rhs = Expr("b");
@@ -147,14 +160,15 @@
 
   td.RegisterVariableForTesting(coord_var);
   td.RegisterVariableForTesting(b_var);
-  gen.register_global(coord_var);
-  gen.register_global(b_var);
-  mod->AddGlobalVariable(coord_var);
-  mod->AddGlobalVariable(b_var);
 
   ASSERT_TRUE(td.Determine()) << td.error();
   ASSERT_TRUE(td.DetermineResultType(assign));
 
+  GeneratorImpl& gen = Build();
+
+  gen.register_global(coord_var);
+  gen.register_global(b_var);
+
   ASSERT_TRUE(gen.EmitStatement(out, assign)) << gen.error();
   EXPECT_EQ(result(), R"(float3x2 _tint_tmp = b;
 data.Store3(4 + 0, asuint(_tint_tmp[0]));
@@ -183,19 +197,21 @@
 
   auto* s = ty.struct_("Data", str);
   auto* coord_var = Var("data", ast::StorageClass::kStorage, s);
+  mod->AddGlobalVariable(coord_var);
+  td.RegisterVariableForTesting(coord_var);
 
   auto* lhs = MemberAccessor("data", "a");
   auto* rhs = Construct(ty.mat2x3<f32>(), ast::ExpressionList{});
 
   auto* assign = create<ast::AssignmentStatement>(lhs, rhs);
 
-  td.RegisterVariableForTesting(coord_var);
-  gen.register_global(coord_var);
-  mod->AddGlobalVariable(coord_var);
-
   ASSERT_TRUE(td.Determine()) << td.error();
   ASSERT_TRUE(td.DetermineResultType(assign));
 
+  GeneratorImpl& gen = Build();
+
+  gen.register_global(coord_var);
+
   ASSERT_TRUE(gen.EmitStatement(out, assign)) << gen.error();
   EXPECT_EQ(
       result(),
@@ -224,16 +240,18 @@
 
   auto* s = ty.struct_("Data", str);
   auto* coord_var = Var("data", ast::StorageClass::kStorage, s);
+  mod->AddGlobalVariable(coord_var);
+  td.RegisterVariableForTesting(coord_var);
 
   auto* expr = MemberAccessor("data", "a");
 
-  td.RegisterVariableForTesting(coord_var);
-  gen.register_global(coord_var);
-  mod->AddGlobalVariable(coord_var);
-
   ASSERT_TRUE(td.Determine()) << td.error();
   ASSERT_TRUE(td.DetermineResultType(expr));
 
+  GeneratorImpl& gen = Build();
+
+  gen.register_global(coord_var);
+
   ASSERT_TRUE(gen.EmitExpression(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(),
             "asfloat(uint2x3(data.Load2(4 + 0), data.Load2(4 + 8), "
@@ -264,15 +282,18 @@
 
   auto* s = ty.struct_("Data", str);
   auto* coord_var = Var("data", ast::StorageClass::kStorage, s);
-  auto* expr = MemberAccessor("data", "a");
-
-  td.RegisterVariableForTesting(coord_var);
-  gen.register_global(coord_var);
   mod->AddGlobalVariable(coord_var);
+  td.RegisterVariableForTesting(coord_var);
+
+  auto* expr = MemberAccessor("data", "a");
 
   ASSERT_TRUE(td.Determine()) << td.error();
   ASSERT_TRUE(td.DetermineResultType(expr));
 
+  GeneratorImpl& gen = Build();
+
+  gen.register_global(coord_var);
+
   ASSERT_TRUE(gen.EmitExpression(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(),
             "asfloat(uint3x2(data.Load3(4 + 0), data.Load3(4 + 16)))");
@@ -296,15 +317,18 @@
 
   auto* s = ty.struct_("Data", str);
   auto* coord_var = Var("data", ast::StorageClass::kStorage, s);
-  auto* expr = MemberAccessor("data", "a");
-
-  td.RegisterVariableForTesting(coord_var);
-  gen.register_global(coord_var);
   mod->AddGlobalVariable(coord_var);
+  td.RegisterVariableForTesting(coord_var);
+
+  auto* expr = MemberAccessor("data", "a");
 
   ASSERT_TRUE(td.Determine()) << td.error();
   ASSERT_TRUE(td.DetermineResultType(expr));
 
+  GeneratorImpl& gen = Build();
+
+  gen.register_global(coord_var);
+
   ASSERT_TRUE(gen.EmitExpression(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(),
             "asfloat(uint3x3(data.Load3(0 + 0), data.Load3(0 + 16), "
@@ -329,16 +353,19 @@
 
   auto* s = ty.struct_("Data", str);
   auto* coord_var = Var("data", ast::StorageClass::kStorage, s);
+  mod->AddGlobalVariable(coord_var);
+  td.RegisterVariableForTesting(coord_var);
+
   auto* expr = IndexAccessor(
       IndexAccessor(MemberAccessor("data", "a"), Expr(2)), Expr(1));
 
-  td.RegisterVariableForTesting(coord_var);
-  gen.register_global(coord_var);
-  mod->AddGlobalVariable(coord_var);
-
   ASSERT_TRUE(td.Determine()) << td.error();
   ASSERT_TRUE(td.DetermineResultType(expr));
 
+  GeneratorImpl& gen = Build();
+
+  gen.register_global(coord_var);
+
   ASSERT_TRUE(gen.EmitExpression(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(), "asfloat(data.Load((4 * 1) + (16 * 2) + 16))");
 }
@@ -362,15 +389,18 @@
       ast::StructDecorationList{});
   auto* s = ty.struct_("Data", str);
   auto* coord_var = Var("data", ast::StorageClass::kStorage, s);
-  auto* expr = IndexAccessor(MemberAccessor("data", "a"), Expr(2));
-
-  td.RegisterVariableForTesting(coord_var);
-  gen.register_global(coord_var);
   mod->AddGlobalVariable(coord_var);
+  td.RegisterVariableForTesting(coord_var);
+
+  auto* expr = IndexAccessor(MemberAccessor("data", "a"), Expr(2));
 
   ASSERT_TRUE(td.Determine()) << td.error();
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  GeneratorImpl& gen = Build();
+
+  gen.register_global(coord_var);
+
   ASSERT_TRUE(gen.EmitExpression(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(), "asint(data.Load((4 * 2) + 0))");
 }
@@ -394,16 +424,19 @@
       ast::StructDecorationList{});
   auto* s = ty.struct_("Data", str);
   auto* coord_var = Var("data", ast::StorageClass::kStorage, s);
+  mod->AddGlobalVariable(coord_var);
+  td.RegisterVariableForTesting(coord_var);
+
   auto* expr = IndexAccessor(MemberAccessor("data", "a"),
                              Sub(Add(Expr(2), Expr(4)), Expr(3)));
 
-  td.RegisterVariableForTesting(coord_var);
-  gen.register_global(coord_var);
-  mod->AddGlobalVariable(coord_var);
-
   ASSERT_TRUE(td.Determine()) << td.error();
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  GeneratorImpl& gen = Build();
+
+  gen.register_global(coord_var);
+
   ASSERT_TRUE(gen.EmitExpression(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(), "asint(data.Load((4 * ((2 + 4) - 3)) + 0))");
 }
@@ -426,18 +459,20 @@
 
   auto* s = ty.struct_("Data", str);
   auto* coord_var = Var("data", ast::StorageClass::kStorage, s);
-
-  td.RegisterVariableForTesting(coord_var);
-  gen.register_global(coord_var);
   mod->AddGlobalVariable(coord_var);
-
-  ASSERT_TRUE(td.Determine()) << td.error();
+  td.RegisterVariableForTesting(coord_var);
 
   auto* lhs = MemberAccessor("data", "b");
   auto* rhs = Expr(2.0f);
   auto* assign = create<ast::AssignmentStatement>(lhs, rhs);
 
+  ASSERT_TRUE(td.Determine()) << td.error();
   ASSERT_TRUE(td.DetermineResultType(assign));
+
+  GeneratorImpl& gen = Build();
+
+  gen.register_global(coord_var);
+
   ASSERT_TRUE(gen.EmitStatement(out, assign)) << gen.error();
   EXPECT_EQ(result(), R"(data.Store(4, asuint(2.0f));
 )");
@@ -464,18 +499,20 @@
 
   auto* s = ty.struct_("Data", str);
   auto* coord_var = Var("data", ast::StorageClass::kStorage, s);
-
-  td.RegisterVariableForTesting(coord_var);
-  gen.register_global(coord_var);
   mod->AddGlobalVariable(coord_var);
-
-  ASSERT_TRUE(td.Determine()) << td.error();
+  td.RegisterVariableForTesting(coord_var);
 
   auto* lhs = IndexAccessor(MemberAccessor("data", "a"), Expr(2));
   auto* rhs = Expr(2);
   auto* assign = create<ast::AssignmentStatement>(lhs, rhs);
 
+  ASSERT_TRUE(td.Determine()) << td.error();
   ASSERT_TRUE(td.DetermineResultType(assign)) << td.error();
+
+  GeneratorImpl& gen = Build();
+
+  gen.register_global(coord_var);
+
   ASSERT_TRUE(gen.EmitStatement(out, assign)) << gen.error();
   EXPECT_EQ(result(), R"(data.Store((4 * 2) + 0, asuint(2));
 )");
@@ -499,18 +536,20 @@
 
   auto* s = ty.struct_("Data", str);
   auto* coord_var = Var("data", ast::StorageClass::kStorage, s);
-
-  td.RegisterVariableForTesting(coord_var);
-  gen.register_global(coord_var);
   mod->AddGlobalVariable(coord_var);
-
-  ASSERT_TRUE(td.Determine()) << td.error();
+  td.RegisterVariableForTesting(coord_var);
 
   auto* lhs = MemberAccessor("data", "a");
   auto* rhs = Expr(2);
   auto* assign = create<ast::AssignmentStatement>(lhs, rhs);
 
+  ASSERT_TRUE(td.Determine()) << td.error();
   ASSERT_TRUE(td.DetermineResultType(assign));
+
+  GeneratorImpl& gen = Build();
+
+  gen.register_global(coord_var);
+
   ASSERT_TRUE(gen.EmitStatement(out, assign)) << gen.error();
   EXPECT_EQ(result(), R"(data.Store(0, asuint(2));
 )");
@@ -534,16 +573,18 @@
 
   auto* s = ty.struct_("Data", str);
   auto* coord_var = Var("data", ast::StorageClass::kStorage, s);
-
-  td.RegisterVariableForTesting(coord_var);
-  gen.register_global(coord_var);
   mod->AddGlobalVariable(coord_var);
-
-  ASSERT_TRUE(td.Determine()) << td.error();
+  td.RegisterVariableForTesting(coord_var);
 
   auto* expr = MemberAccessor("data", "b");
 
+  ASSERT_TRUE(td.Determine()) << td.error();
   ASSERT_TRUE(td.DetermineResultType(expr));
+
+  GeneratorImpl& gen = Build();
+
+  gen.register_global(coord_var);
+
   ASSERT_TRUE(gen.EmitExpression(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(), "asfloat(data.Load3(16))");
 }
@@ -566,19 +607,21 @@
 
   auto* s = ty.struct_("Data", str);
   auto* coord_var = Var("data", ast::StorageClass::kStorage, s);
-
-  td.RegisterVariableForTesting(coord_var);
-  gen.register_global(coord_var);
   mod->AddGlobalVariable(coord_var);
-
-  ASSERT_TRUE(td.Determine()) << td.error();
+  td.RegisterVariableForTesting(coord_var);
 
   auto* lhs = MemberAccessor("data", "b");
   auto* rhs = vec3<f32>(1.f, 2.f, 3.f);
 
   auto* assign = create<ast::AssignmentStatement>(lhs, rhs);
 
+  ASSERT_TRUE(td.Determine()) << td.error();
   ASSERT_TRUE(td.DetermineResultType(assign));
+
+  GeneratorImpl& gen = Build();
+
+  gen.register_global(coord_var);
+
   ASSERT_TRUE(gen.EmitStatement(out, assign)) << gen.error();
   EXPECT_EQ(result(),
             R"(data.Store3(16, asuint(float3(1.0f, 2.0f, 3.0f)));
@@ -619,17 +662,19 @@
 
   auto* pre_struct = ty.struct_("Pre", pre_str);
   auto* coord_var = Var("data", ast::StorageClass::kStorage, pre_struct);
-
-  td.RegisterVariableForTesting(coord_var);
-  gen.register_global(coord_var);
   mod->AddGlobalVariable(coord_var);
-
-  ASSERT_TRUE(td.Determine()) << td.error();
+  td.RegisterVariableForTesting(coord_var);
 
   auto* expr =
       MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), Expr(2)), "b");
 
+  ASSERT_TRUE(td.Determine()) << td.error();
   ASSERT_TRUE(td.DetermineResultType(expr));
+
+  GeneratorImpl& gen = Build();
+
+  gen.register_global(coord_var);
+
   ASSERT_TRUE(gen.EmitExpression(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(), "asfloat(data.Load3(16 + (32 * 2) + 0))");
 }
@@ -666,18 +711,21 @@
 
   auto* pre_struct = ty.struct_("Pre", pre_str);
   auto* coord_var = Var("data", ast::StorageClass::kStorage, pre_struct);
-
-  td.RegisterVariableForTesting(coord_var);
-  gen.register_global(coord_var);
   mod->AddGlobalVariable(coord_var);
 
-  ASSERT_TRUE(td.Determine()) << td.error();
+  td.RegisterVariableForTesting(coord_var);
 
   auto* expr = MemberAccessor(
       MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), Expr(2)), "b"),
       "xy");
 
+  ASSERT_TRUE(td.Determine()) << td.error();
   ASSERT_TRUE(td.DetermineResultType(expr));
+
+  GeneratorImpl& gen = Build();
+
+  gen.register_global(coord_var);
+
   ASSERT_TRUE(gen.EmitExpression(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(), "asfloat(data.Load3(16 + (32 * 2) + 0)).xy");
 }
@@ -717,18 +765,20 @@
 
   auto* pre_struct = ty.struct_("Pre", pre_str);
   auto* coord_var = Var("data", ast::StorageClass::kStorage, pre_struct);
-
-  td.RegisterVariableForTesting(coord_var);
-  gen.register_global(coord_var);
   mod->AddGlobalVariable(coord_var);
-
-  ASSERT_TRUE(td.Determine()) << td.error();
+  td.RegisterVariableForTesting(coord_var);
 
   auto* expr = MemberAccessor(
       MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), Expr(2)), "b"),
       "g");
 
+  ASSERT_TRUE(td.Determine()) << td.error();
   ASSERT_TRUE(td.DetermineResultType(expr));
+
+  GeneratorImpl& gen = Build();
+
+  gen.register_global(coord_var);
+
   ASSERT_TRUE(gen.EmitExpression(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(), "asfloat(data.Load((4 * 1) + 16 + (32 * 2) + 0))");
 }
@@ -767,18 +817,20 @@
 
   auto* pre_struct = ty.struct_("Pre", pre_str);
   auto* coord_var = Var("data", ast::StorageClass::kStorage, pre_struct);
-
-  td.RegisterVariableForTesting(coord_var);
-  gen.register_global(coord_var);
   mod->AddGlobalVariable(coord_var);
-
-  ASSERT_TRUE(td.Determine()) << td.error();
+  td.RegisterVariableForTesting(coord_var);
 
   auto* expr = IndexAccessor(
       MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), Expr(2)), "b"),
       Expr(1));
 
+  ASSERT_TRUE(td.Determine()) << td.error();
   ASSERT_TRUE(td.DetermineResultType(expr));
+
+  GeneratorImpl& gen = Build();
+
+  gen.register_global(coord_var);
+
   ASSERT_TRUE(gen.EmitExpression(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(), "asfloat(data.Load((4 * 1) + 16 + (32 * 2) + 0))");
 }
@@ -817,12 +869,8 @@
 
   auto* pre_struct = ty.struct_("Pre", pre_str);
   auto* coord_var = Var("data", ast::StorageClass::kStorage, pre_struct);
-
-  td.RegisterVariableForTesting(coord_var);
-  gen.register_global(coord_var);
   mod->AddGlobalVariable(coord_var);
-
-  ASSERT_TRUE(td.Determine()) << td.error();
+  td.RegisterVariableForTesting(coord_var);
 
   auto* lhs =
       MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), Expr(2)), "b");
@@ -830,7 +878,13 @@
   auto* assign =
       create<ast::AssignmentStatement>(lhs, vec3<f32>(1.f, 2.f, 3.f));
 
+  ASSERT_TRUE(td.Determine()) << td.error();
   ASSERT_TRUE(td.DetermineResultType(assign));
+
+  GeneratorImpl& gen = Build();
+
+  gen.register_global(coord_var);
+
   ASSERT_TRUE(gen.EmitStatement(out, assign)) << gen.error();
   EXPECT_EQ(result(),
             R"(data.Store3(16 + (32 * 2) + 0, asuint(float3(1.0f, 2.0f, 3.0f)));
@@ -871,12 +925,8 @@
 
   auto* pre_struct = ty.struct_("Pre", pre_str);
   auto* coord_var = Var("data", ast::StorageClass::kStorage, pre_struct);
-
-  td.RegisterVariableForTesting(coord_var);
-  gen.register_global(coord_var);
   mod->AddGlobalVariable(coord_var);
-
-  ASSERT_TRUE(td.Determine()) << td.error();
+  td.RegisterVariableForTesting(coord_var);
 
   auto* lhs = MemberAccessor(
       MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), Expr(2)), "b"),
@@ -885,7 +935,13 @@
 
   auto* assign = create<ast::AssignmentStatement>(lhs, rhs);
 
+  ASSERT_TRUE(td.Determine()) << td.error();
   ASSERT_TRUE(td.DetermineResultType(assign));
+
+  GeneratorImpl& gen = Build();
+
+  gen.register_global(coord_var);
+
   ASSERT_TRUE(gen.EmitStatement(out, assign)) << gen.error();
   EXPECT_EQ(result(),
             R"(data.Store((4 * 1) + 16 + (32 * 2) + 0, asuint(1.0f));
diff --git a/src/writer/hlsl/generator_impl_module_constant_test.cc b/src/writer/hlsl/generator_impl_module_constant_test.cc
index b8ec558..057162f 100644
--- a/src/writer/hlsl/generator_impl_module_constant_test.cc
+++ b/src/writer/hlsl/generator_impl_module_constant_test.cc
@@ -19,10 +19,10 @@
 #include "src/ast/float_literal.h"
 #include "src/ast/module.h"
 #include "src/ast/scalar_constructor_expression.h"
-#include "src/type/array_type.h"
-#include "src/type/f32_type.h"
 #include "src/ast/type_constructor_expression.h"
 #include "src/ast/variable.h"
+#include "src/type/array_type.h"
+#include "src/type/f32_type.h"
 #include "src/writer/hlsl/test_helper.h"
 
 namespace tint {
@@ -37,6 +37,8 @@
       Const("pos", ast::StorageClass::kNone, ty.array<f32, 3>(),
             array<f32, 3>(1.f, 2.f, 3.f), ast::VariableDecorationList{});
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitProgramConstVariable(out, var)) << gen.error();
   EXPECT_EQ(result(), "static const float pos[3] = {1.0f, 2.0f, 3.0f};\n");
 }
@@ -47,6 +49,8 @@
                         create<ast::ConstantIdDecoration>(23),
                     });
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitProgramConstVariable(out, var)) << gen.error();
   EXPECT_EQ(result(), R"(#ifndef WGSL_SPEC_CONSTANT_23
 #define WGSL_SPEC_CONSTANT_23 3.0f
@@ -62,6 +66,8 @@
                         create<ast::ConstantIdDecoration>(23),
                     });
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitProgramConstVariable(out, var)) << gen.error();
   EXPECT_EQ(result(), R"(#ifndef WGSL_SPEC_CONSTANT_23
 #error spec constant required for constant id 23
diff --git a/src/writer/hlsl/generator_impl_return_test.cc b/src/writer/hlsl/generator_impl_return_test.cc
index 92939e4..4c04d90 100644
--- a/src/writer/hlsl/generator_impl_return_test.cc
+++ b/src/writer/hlsl/generator_impl_return_test.cc
@@ -29,6 +29,9 @@
 
 TEST_F(HlslGeneratorImplTest_Return, Emit_Return) {
   auto* r = create<ast::ReturnStatement>();
+
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(out, r)) << gen.error();
@@ -37,6 +40,9 @@
 
 TEST_F(HlslGeneratorImplTest_Return, Emit_ReturnWithValue) {
   auto* r = create<ast::ReturnStatement>(Expr("expr"));
+
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(out, r)) << gen.error();
diff --git a/src/writer/hlsl/generator_impl_switch_test.cc b/src/writer/hlsl/generator_impl_switch_test.cc
index 17d8666..75039eb 100644
--- a/src/writer/hlsl/generator_impl_switch_test.cc
+++ b/src/writer/hlsl/generator_impl_switch_test.cc
@@ -51,6 +51,9 @@
 
   auto* cond = Expr("cond");
   auto* s = create<ast::SwitchStatement>(cond, body);
+
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(out, s)) << gen.error();
diff --git a/src/writer/hlsl/generator_impl_test.cc b/src/writer/hlsl/generator_impl_test.cc
index 27476ae..a4f4ffc 100644
--- a/src/writer/hlsl/generator_impl_test.cc
+++ b/src/writer/hlsl/generator_impl_test.cc
@@ -32,6 +32,8 @@
                     ast::StatementList{}, ast::FunctionDecorationList{});
   mod->AddFunction(func);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.Generate(out)) << gen.error();
   EXPECT_EQ(result(), R"(void my_func() {
 }
@@ -40,11 +42,15 @@
 }
 
 TEST_F(HlslGeneratorImplTest, InputStructName) {
+  GeneratorImpl& gen = Build();
+
   ASSERT_EQ(gen.generate_name("func_main_in"), "func_main_in");
 }
 
 TEST_F(HlslGeneratorImplTest, InputStructName_ConflictWithExisting) {
   // Register the struct name as existing.
+  GeneratorImpl& gen = Build();
+
   auto* namer = gen.namer_for_testing();
   namer->NameFor("func_main_out");
 
@@ -52,9 +58,12 @@
 }
 
 TEST_F(HlslGeneratorImplTest, NameConflictWith_InputStructName) {
-  ASSERT_EQ(gen.generate_name("func_main_in"), "func_main_in");
+  auto* expr = Expr("func_main_in");
 
-  ASSERT_TRUE(gen.EmitIdentifier(pre, out, Expr("func_main_in")));
+  GeneratorImpl& gen = Build();
+
+  ASSERT_EQ(gen.generate_name("func_main_in"), "func_main_in");
+  ASSERT_TRUE(gen.EmitIdentifier(pre, out, expr));
   EXPECT_EQ(result(), "func_main_in_0");
 }
 
@@ -69,6 +78,8 @@
 using HlslBuiltinConversionTest = TestParamHelper<HlslBuiltinData>;
 TEST_P(HlslBuiltinConversionTest, Emit) {
   auto params = GetParam();
+  GeneratorImpl& gen = Build();
+
   EXPECT_EQ(gen.builtin_to_attribute(params.builtin),
             std::string(params.attribute_name));
 }
diff --git a/src/writer/hlsl/generator_impl_type_test.cc b/src/writer/hlsl/generator_impl_type_test.cc
index 2655b22..2d69d2b 100644
--- a/src/writer/hlsl/generator_impl_type_test.cc
+++ b/src/writer/hlsl/generator_impl_type_test.cc
@@ -47,6 +47,8 @@
 TEST_F(HlslGeneratorImplTest_Type, EmitType_Alias) {
   auto* alias = ty.alias("alias", ty.f32);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(out, alias, "")) << gen.error();
   EXPECT_EQ(result(), "alias");
 }
@@ -54,17 +56,24 @@
 TEST_F(HlslGeneratorImplTest_Type, EmitType_Alias_NameCollision) {
   auto* alias = ty.alias("bool", ty.f32);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(out, alias, "")) << gen.error();
   EXPECT_EQ(result(), "bool_tint_0");
 }
 
 TEST_F(HlslGeneratorImplTest_Type, EmitType_Array) {
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(out, ty.array<bool, 4>(), "ary")) << gen.error();
   EXPECT_EQ(result(), "bool ary[4]");
 }
 
 TEST_F(HlslGeneratorImplTest_Type, EmitType_ArrayOfArray) {
   auto* arr = ty.array(ty.array<bool, 4>(), 5);
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(out, arr, "ary")) << gen.error();
   EXPECT_EQ(result(), "bool ary[5][4]");
 }
@@ -73,53 +82,75 @@
 TEST_F(HlslGeneratorImplTest_Type,
        DISABLED_EmitType_ArrayOfArrayOfRuntimeArray) {
   auto* arr = ty.array(ty.array(ty.array<bool, 4>(), 5), 0);
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(out, arr, "ary")) << gen.error();
   EXPECT_EQ(result(), "bool ary[5][4][1]");
 }
 
 TEST_F(HlslGeneratorImplTest_Type, EmitType_ArrayOfArrayOfArray) {
   auto* arr = ty.array(ty.array(ty.array<bool, 4>(), 5), 6);
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(out, arr, "ary")) << gen.error();
   EXPECT_EQ(result(), "bool ary[6][5][4]");
 }
 
 TEST_F(HlslGeneratorImplTest_Type, EmitType_Array_NameCollision) {
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(out, ty.array<bool, 4>(), "bool")) << gen.error();
   EXPECT_EQ(result(), "bool bool_tint_0[4]");
 }
 
 TEST_F(HlslGeneratorImplTest_Type, EmitType_Array_WithoutName) {
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(out, ty.array<bool, 4>(), "")) << gen.error();
   EXPECT_EQ(result(), "bool[4]");
 }
 
 TEST_F(HlslGeneratorImplTest_Type, DISABLED_EmitType_RuntimeArray) {
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(out, ty.array<bool>(), "ary")) << gen.error();
   EXPECT_EQ(result(), "bool ary[]");
 }
 
 TEST_F(HlslGeneratorImplTest_Type,
        DISABLED_EmitType_RuntimeArray_NameCollision) {
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(out, ty.array<bool>(), "double")) << gen.error();
   EXPECT_EQ(result(), "bool double_tint_0[]");
 }
 
 TEST_F(HlslGeneratorImplTest_Type, EmitType_Bool) {
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(out, ty.bool_, "")) << gen.error();
   EXPECT_EQ(result(), "bool");
 }
 
 TEST_F(HlslGeneratorImplTest_Type, EmitType_F32) {
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(out, ty.f32, "")) << gen.error();
   EXPECT_EQ(result(), "float");
 }
 
 TEST_F(HlslGeneratorImplTest_Type, EmitType_I32) {
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(out, ty.i32, "")) << gen.error();
   EXPECT_EQ(result(), "int");
 }
 
 TEST_F(HlslGeneratorImplTest_Type, EmitType_Matrix) {
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(out, ty.mat2x3<f32>(), "")) << gen.error();
   EXPECT_EQ(result(), "float3x2");
 }
@@ -128,6 +159,8 @@
 TEST_F(HlslGeneratorImplTest_Type, DISABLED_EmitType_Pointer) {
   type::Pointer p(ty.f32, ast::StorageClass::kWorkgroup);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(out, &p, "")) << gen.error();
   EXPECT_EQ(result(), "float*");
 }
@@ -139,6 +172,8 @@
       ast::StructDecorationList{});
 
   auto* s = ty.struct_("S", str);
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitStructType(out, s, "S")) << gen.error();
   EXPECT_EQ(result(), R"(struct S {
   int a;
@@ -154,6 +189,8 @@
       ast::StructDecorationList{});
 
   auto* s = ty.struct_("S", str);
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(out, s, "")) << gen.error();
   EXPECT_EQ(result(), "S");
 }
@@ -166,6 +203,8 @@
       ast::StructDecorationList{});
 
   auto* s = ty.struct_("S", str);
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(out, s, "")) << gen.error();
   EXPECT_EQ(result(), R"(struct {
   int8_t pad_0[4];
@@ -183,6 +222,8 @@
       ast::StructDecorationList{});
 
   auto* s = ty.struct_("S", str);
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitStructType(out, s, "S")) << gen.error();
   EXPECT_EQ(result(), R"(struct S {
   int double_tint_0;
@@ -202,6 +243,8 @@
       decos);
 
   auto* s = ty.struct_("S", str);
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitStructType(out, s, "B")) << gen.error();
   EXPECT_EQ(result(), R"(struct B {
   int a;
@@ -210,16 +253,22 @@
 }
 
 TEST_F(HlslGeneratorImplTest_Type, EmitType_U32) {
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(out, ty.u32, "")) << gen.error();
   EXPECT_EQ(result(), "uint");
 }
 
 TEST_F(HlslGeneratorImplTest_Type, EmitType_Vector) {
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(out, ty.vec3<f32>(), "")) << gen.error();
   EXPECT_EQ(result(), "float3");
 }
 
 TEST_F(HlslGeneratorImplTest_Type, EmitType_Void) {
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(out, ty.void_, "")) << gen.error();
   EXPECT_EQ(result(), "void");
 }
@@ -227,6 +276,8 @@
 TEST_F(HlslGeneratorImplTest_Type, EmitSampler) {
   type::Sampler sampler(type::SamplerKind::kSampler);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(out, &sampler, "")) << gen.error();
   EXPECT_EQ(result(), "SamplerState");
 }
@@ -234,6 +285,8 @@
 TEST_F(HlslGeneratorImplTest_Type, EmitSamplerComparison) {
   type::Sampler sampler(type::SamplerKind::kComparisonSampler);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(out, &sampler, "")) << gen.error();
   EXPECT_EQ(result(), "SamplerComparisonState");
 }
@@ -252,6 +305,8 @@
 
   type::DepthTexture s(params.dim);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(out, &s, "")) << gen.error();
   EXPECT_EQ(result(), params.result);
 }
@@ -280,6 +335,8 @@
 
   type::SampledTexture s(params.dim, ty.f32);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(out, &s, "")) << gen.error();
   EXPECT_EQ(result(), params.result);
 }
@@ -299,6 +356,8 @@
 TEST_F(HlslGeneratorImplTest_Type, EmitMultisampledTexture) {
   type::MultisampledTexture s(type::TextureDimension::k2d, ty.f32);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(out, &s, "")) << gen.error();
   EXPECT_EQ(result(), "Texture2D");
 }
@@ -323,6 +382,8 @@
                                    : ast::AccessControl::kWriteOnly,
                          &s);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(out, &ac, "")) << gen.error();
   EXPECT_EQ(result(), params.result);
 }
diff --git a/src/writer/hlsl/generator_impl_unary_op_test.cc b/src/writer/hlsl/generator_impl_unary_op_test.cc
index 77fdf7a..48294c1 100644
--- a/src/writer/hlsl/generator_impl_unary_op_test.cc
+++ b/src/writer/hlsl/generator_impl_unary_op_test.cc
@@ -40,6 +40,8 @@
   auto* expr = Expr("expr");
   auto* op = create<ast::UnaryOpExpression>(params.op, expr);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitExpression(pre, out, op)) << gen.error();
   EXPECT_EQ(result(), std::string(params.name) + "(expr)");
 }
diff --git a/src/writer/hlsl/generator_impl_variable_decl_statement_test.cc b/src/writer/hlsl/generator_impl_variable_decl_statement_test.cc
index 10e62fe..91ca67e 100644
--- a/src/writer/hlsl/generator_impl_variable_decl_statement_test.cc
+++ b/src/writer/hlsl/generator_impl_variable_decl_statement_test.cc
@@ -36,6 +36,9 @@
   auto* var = Var("a", ast::StorageClass::kNone, ty.f32);
 
   auto* stmt = create<ast::VariableDeclStatement>(var);
+
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(out, stmt)) << gen.error();
@@ -46,6 +49,9 @@
   auto* var = Const("a", ast::StorageClass::kNone, ty.f32);
 
   auto* stmt = create<ast::VariableDeclStatement>(var);
+
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(out, stmt)) << gen.error();
@@ -56,6 +62,9 @@
   auto* var = Var("a", ast::StorageClass::kNone, ty.array<f32, 5>());
 
   auto* stmt = create<ast::VariableDeclStatement>(var);
+
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(out, stmt)) << gen.error();
@@ -67,6 +76,9 @@
   auto* var = Var("a", ast::StorageClass::kFunction, ty.f32);
 
   auto* stmt = create<ast::VariableDeclStatement>(var);
+
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(out, stmt)) << gen.error();
@@ -77,6 +89,9 @@
   auto* var = Var("a", ast::StorageClass::kPrivate, ty.f32);
 
   auto* stmt = create<ast::VariableDeclStatement>(var);
+
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(out, stmt)) << gen.error();
@@ -89,6 +104,9 @@
                   ast::VariableDecorationList{});
 
   auto* stmt = create<ast::VariableDeclStatement>(var);
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitStatement(out, stmt)) << gen.error();
   EXPECT_EQ(result(), R"(float a = initializer;
 )");
@@ -100,6 +118,9 @@
                   ast::VariableDecorationList{});
 
   auto* stmt = create<ast::VariableDeclStatement>(var);
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitStatement(out, stmt)) << gen.error();
   EXPECT_EQ(result(), R"(float3 a = float3(0.0f);
 )");
@@ -111,6 +132,9 @@
                   mat2x3<f32>(), ast::VariableDecorationList{});
 
   auto* stmt = create<ast::VariableDeclStatement>(var);
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitStatement(out, stmt)) << gen.error();
   EXPECT_EQ(result(),
             R"(float3x2 a = float3x2(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
diff --git a/src/writer/hlsl/test_helper.h b/src/writer/hlsl/test_helper.h
index fd874f4..af3d10a 100644
--- a/src/writer/hlsl/test_helper.h
+++ b/src/writer/hlsl/test_helper.h
@@ -33,9 +33,21 @@
 template <typename BODY>
 class TestHelperBase : public BODY, public ast::BuilderWithModule {
  public:
-  TestHelperBase() : td(mod), gen(mod) {}
+  TestHelperBase() : td(mod) {}
   ~TestHelperBase() = default;
 
+  /// Builds and returns a GeneratorImpl from the module.
+  /// @note The generator is only built once. Multiple calls to Build() will
+  /// return the same GeneratorImpl without rebuilding.
+  /// @return the built generator
+  GeneratorImpl& Build() {
+    if (gen_) {
+      return *gen_;
+    }
+    gen_ = std::make_unique<GeneratorImpl>(mod);
+    return *gen_;
+  }
+
   /// @returns the result string
   std::string result() const { return out.str(); }
 
@@ -44,13 +56,14 @@
 
   /// The type determiner
   TypeDeterminer td;
-  /// The generator
-  GeneratorImpl gen;
 
   /// The output stream
   std::ostringstream out;
   /// The pre-output stream
   std::ostringstream pre;
+
+ private:
+  std::unique_ptr<GeneratorImpl> gen_;
 };
 using TestHelper = TestHelperBase<testing::Test>;
 
diff --git a/src/writer/msl/generator_impl_alias_type_test.cc b/src/writer/msl/generator_impl_alias_type_test.cc
index 0648d20..055d804 100644
--- a/src/writer/msl/generator_impl_alias_type_test.cc
+++ b/src/writer/msl/generator_impl_alias_type_test.cc
@@ -30,6 +30,8 @@
 TEST_F(MslGeneratorImplTest, EmitConstructedType_F32) {
   auto* alias = ty.alias("a", ty.f32);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitConstructedType(alias)) << gen.error();
   EXPECT_EQ(gen.result(), R"(typedef float a;
 )");
@@ -38,6 +40,8 @@
 TEST_F(MslGeneratorImplTest, EmitConstructedType_NameCollision) {
   auto* alias = ty.alias("float", ty.f32);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitConstructedType(alias)) << gen.error();
   EXPECT_EQ(gen.result(), R"(typedef float float_tint_0;
 )");
@@ -50,6 +54,9 @@
       ast::StructDecorationList{});
 
   auto* s = ty.struct_("a", str);
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitConstructedType(s)) << gen.error();
   EXPECT_EQ(gen.result(), R"(struct a {
   float a;
@@ -67,6 +74,8 @@
   auto* s = ty.struct_("b", str);
   auto* alias = ty.alias("a", s);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitConstructedType(alias)) << gen.error();
   EXPECT_EQ(gen.result(), R"(typedef b a;
 )");
diff --git a/src/writer/msl/generator_impl_array_accessor_test.cc b/src/writer/msl/generator_impl_array_accessor_test.cc
index 9f8cda6..e8e6ce3 100644
--- a/src/writer/msl/generator_impl_array_accessor_test.cc
+++ b/src/writer/msl/generator_impl_array_accessor_test.cc
@@ -34,6 +34,8 @@
 TEST_F(MslGeneratorImplTest, EmitExpression_ArrayAccessor) {
   auto* expr = IndexAccessor(Expr("ary"), 5);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitExpression(expr)) << gen.error();
   EXPECT_EQ(gen.result(), "ary[5]");
 }
@@ -41,6 +43,8 @@
 TEST_F(MslGeneratorImplTest, EmitArrayAccessor) {
   auto* expr = IndexAccessor(Expr("ary"), Expr("idx"));
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitArrayAccessor(expr->As<ast::ArrayAccessorExpression>()))
       << gen.error();
   EXPECT_EQ(gen.result(), "ary[idx]");
diff --git a/src/writer/msl/generator_impl_assign_test.cc b/src/writer/msl/generator_impl_assign_test.cc
index 6f7c70f..2266646 100644
--- a/src/writer/msl/generator_impl_assign_test.cc
+++ b/src/writer/msl/generator_impl_assign_test.cc
@@ -31,6 +31,9 @@
 
 TEST_F(MslGeneratorImplTest, Emit_Assign) {
   auto* assign = create<ast::AssignmentStatement>(Expr("lhs"), Expr("rhs"));
+
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(assign)) << gen.error();
diff --git a/src/writer/msl/generator_impl_binary_test.cc b/src/writer/msl/generator_impl_binary_test.cc
index b1b6ed0..70b4498 100644
--- a/src/writer/msl/generator_impl_binary_test.cc
+++ b/src/writer/msl/generator_impl_binary_test.cc
@@ -40,6 +40,9 @@
 
   auto* expr =
       create<ast::BinaryExpression>(params.op, Expr("left"), Expr("right"));
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitExpression(expr)) << gen.error();
   EXPECT_EQ(gen.result(), params.result);
 }
diff --git a/src/writer/msl/generator_impl_bitcast_test.cc b/src/writer/msl/generator_impl_bitcast_test.cc
index 372a889..fea3c59 100644
--- a/src/writer/msl/generator_impl_bitcast_test.cc
+++ b/src/writer/msl/generator_impl_bitcast_test.cc
@@ -31,6 +31,9 @@
 
 TEST_F(MslGeneratorImplTest, EmitExpression_Bitcast) {
   auto* bitcast = create<ast::BitcastExpression>(ty.f32, Expr("id"));
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitExpression(bitcast)) << gen.error();
   EXPECT_EQ(gen.result(), "as_type<float>(id)");
 }
diff --git a/src/writer/msl/generator_impl_block_test.cc b/src/writer/msl/generator_impl_block_test.cc
index b355ed2..c459ff0 100644
--- a/src/writer/msl/generator_impl_block_test.cc
+++ b/src/writer/msl/generator_impl_block_test.cc
@@ -31,6 +31,9 @@
   auto* b = create<ast::BlockStatement>(ast::StatementList{
       create<ast::DiscardStatement>(),
   });
+
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(b)) << gen.error();
@@ -44,6 +47,9 @@
   auto* b = create<ast::BlockStatement>(ast::StatementList{
       create<ast::DiscardStatement>(),
   });
+
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitBlock(b)) << gen.error();
diff --git a/src/writer/msl/generator_impl_break_test.cc b/src/writer/msl/generator_impl_break_test.cc
index b0a6410..1c88fe2 100644
--- a/src/writer/msl/generator_impl_break_test.cc
+++ b/src/writer/msl/generator_impl_break_test.cc
@@ -31,6 +31,8 @@
 TEST_F(MslGeneratorImplTest, Emit_Break) {
   auto* b = create<ast::BreakStatement>();
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(b)) << gen.error();
diff --git a/src/writer/msl/generator_impl_call_test.cc b/src/writer/msl/generator_impl_call_test.cc
index 6df0f19..44159f8 100644
--- a/src/writer/msl/generator_impl_call_test.cc
+++ b/src/writer/msl/generator_impl_call_test.cc
@@ -37,6 +37,8 @@
                     ast::StatementList{}, ast::FunctionDecorationList{});
   mod->AddFunction(func);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitExpression(call)) << gen.error();
   EXPECT_EQ(gen.result(), "my_func()");
 }
@@ -47,6 +49,8 @@
                     ast::StatementList{}, ast::FunctionDecorationList{});
   mod->AddFunction(func);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitExpression(call)) << gen.error();
   EXPECT_EQ(gen.result(), "my_func(param1, param2)");
 }
@@ -59,6 +63,8 @@
 
   auto* expr = create<ast::CallStatement>(call);
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
   ASSERT_TRUE(gen.EmitStatement(expr)) << gen.error();
   EXPECT_EQ(gen.result(), "  my_func(param1, param2);\n");
diff --git a/src/writer/msl/generator_impl_case_test.cc b/src/writer/msl/generator_impl_case_test.cc
index a37f33e..bb550b9 100644
--- a/src/writer/msl/generator_impl_case_test.cc
+++ b/src/writer/msl/generator_impl_case_test.cc
@@ -40,6 +40,8 @@
   lit.push_back(create<ast::SintLiteral>(ty.i32, 5));
   auto* c = create<ast::CaseStatement>(lit, body);
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitCase(c)) << gen.error();
@@ -55,6 +57,8 @@
   auto* c = create<ast::CaseStatement>(
       lit, create<ast::BlockStatement>(ast::StatementList{}));
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitCase(c)) << gen.error();
@@ -72,6 +76,8 @@
   lit.push_back(create<ast::SintLiteral>(ty.i32, 5));
   auto* c = create<ast::CaseStatement>(lit, body);
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitCase(c)) << gen.error();
@@ -90,6 +96,8 @@
   lit.push_back(create<ast::SintLiteral>(ty.i32, 6));
   auto* c = create<ast::CaseStatement>(lit, body);
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitCase(c)) << gen.error();
@@ -106,6 +114,8 @@
   });
   auto* c = create<ast::CaseStatement>(ast::CaseSelectorList{}, body);
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitCase(c)) << gen.error();
diff --git a/src/writer/msl/generator_impl_cast_test.cc b/src/writer/msl/generator_impl_cast_test.cc
index 1377987..85b8d6a 100644
--- a/src/writer/msl/generator_impl_cast_test.cc
+++ b/src/writer/msl/generator_impl_cast_test.cc
@@ -33,6 +33,8 @@
 TEST_F(MslGeneratorImplTest, EmitExpression_Cast_Scalar) {
   auto* cast = Construct<f32>("id");
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitExpression(cast)) << gen.error();
   EXPECT_EQ(gen.result(), "float(id)");
 }
@@ -40,6 +42,8 @@
 TEST_F(MslGeneratorImplTest, EmitExpression_Cast_Vector) {
   auto* cast = vec3<f32>("id");
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitExpression(cast)) << gen.error();
   EXPECT_EQ(gen.result(), "float3(id)");
 }
diff --git a/src/writer/msl/generator_impl_constructor_test.cc b/src/writer/msl/generator_impl_constructor_test.cc
index aa38874..3da5647 100644
--- a/src/writer/msl/generator_impl_constructor_test.cc
+++ b/src/writer/msl/generator_impl_constructor_test.cc
@@ -39,18 +39,27 @@
 
 TEST_F(MslGeneratorImplTest, EmitConstructor_Bool) {
   auto* expr = Expr(false);
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitConstructor(expr)) << gen.error();
   EXPECT_EQ(gen.result(), "false");
 }
 
 TEST_F(MslGeneratorImplTest, EmitConstructor_Int) {
   auto* expr = Expr(-12345);
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitConstructor(expr)) << gen.error();
   EXPECT_EQ(gen.result(), "-12345");
 }
 
 TEST_F(MslGeneratorImplTest, EmitConstructor_UInt) {
   auto* expr = Expr(56779u);
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitConstructor(expr)) << gen.error();
   EXPECT_EQ(gen.result(), "56779u");
 }
@@ -58,42 +67,63 @@
 TEST_F(MslGeneratorImplTest, EmitConstructor_Float) {
   // Use a number close to 1<<30 but whose decimal representation ends in 0.
   auto* expr = Expr(static_cast<float>((1 << 30) - 4));
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitConstructor(expr)) << gen.error();
   EXPECT_EQ(gen.result(), "1073741824.0f");
 }
 
 TEST_F(MslGeneratorImplTest, EmitConstructor_Type_Float) {
   auto* expr = Construct<f32>(-1.2e-5f);
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitConstructor(expr)) << gen.error();
   EXPECT_EQ(gen.result(), "float(-0.000012f)");
 }
 
 TEST_F(MslGeneratorImplTest, EmitConstructor_Type_Bool) {
   auto* expr = Construct<bool>(true);
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitConstructor(expr)) << gen.error();
   EXPECT_EQ(gen.result(), "bool(true)");
 }
 
 TEST_F(MslGeneratorImplTest, EmitConstructor_Type_Int) {
   auto* expr = Construct<i32>(-12345);
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitConstructor(expr)) << gen.error();
   EXPECT_EQ(gen.result(), "int(-12345)");
 }
 
 TEST_F(MslGeneratorImplTest, EmitConstructor_Type_Uint) {
   auto* expr = Construct<u32>(12345u);
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitConstructor(expr)) << gen.error();
   EXPECT_EQ(gen.result(), "uint(12345u)");
 }
 
 TEST_F(MslGeneratorImplTest, EmitConstructor_Type_Vec) {
   auto* expr = vec3<f32>(1.f, 2.f, 3.f);
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitConstructor(expr)) << gen.error();
   EXPECT_EQ(gen.result(), "float3(1.0f, 2.0f, 3.0f)");
 }
 
 TEST_F(MslGeneratorImplTest, EmitConstructor_Type_Vec_Empty) {
   auto* expr = vec3<f32>();
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitConstructor(expr)) << gen.error();
   EXPECT_EQ(gen.result(), "float3(0.0f)");
 }
@@ -108,6 +138,9 @@
   }
 
   auto* expr = Construct(ty.mat2x3<f32>(), mat_values);
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitConstructor(expr)) << gen.error();
 
   // A matrix of type T with n columns and m rows can also be constructed from
@@ -128,6 +161,9 @@
   }
 
   auto* expr = Construct(&ary, ary_values);
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitConstructor(expr)) << gen.error();
   EXPECT_EQ(gen.result(),
             "{float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), "
diff --git a/src/writer/msl/generator_impl_continue_test.cc b/src/writer/msl/generator_impl_continue_test.cc
index 12719b4..4ef8b55 100644
--- a/src/writer/msl/generator_impl_continue_test.cc
+++ b/src/writer/msl/generator_impl_continue_test.cc
@@ -31,6 +31,8 @@
 TEST_F(MslGeneratorImplTest, Emit_Continue) {
   auto* c = create<ast::ContinueStatement>();
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(c)) << gen.error();
diff --git a/src/writer/msl/generator_impl_discard_test.cc b/src/writer/msl/generator_impl_discard_test.cc
index 0349acf..c59bc5e 100644
--- a/src/writer/msl/generator_impl_discard_test.cc
+++ b/src/writer/msl/generator_impl_discard_test.cc
@@ -28,6 +28,8 @@
 TEST_F(MslGeneratorImplTest, Emit_Discard) {
   auto* stmt = create<ast::DiscardStatement>();
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(stmt)) << gen.error();
diff --git a/src/writer/msl/generator_impl_function_entry_point_data_test.cc b/src/writer/msl/generator_impl_function_entry_point_data_test.cc
index dbe62b9..8271f72 100644
--- a/src/writer/msl/generator_impl_function_entry_point_data_test.cc
+++ b/src/writer/msl/generator_impl_function_entry_point_data_test.cc
@@ -75,6 +75,8 @@
 
   ASSERT_TRUE(td.Determine()) << td.error();
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitEntryPointData(func)) << gen.error();
   EXPECT_EQ(gen.result(), R"(struct vtx_main_in {
   float foo [[attribute(0)]];
@@ -121,6 +123,8 @@
 
   ASSERT_TRUE(td.Determine()) << td.error();
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitEntryPointData(func)) << gen.error();
   EXPECT_EQ(gen.result(), R"(struct vtx_main_out {
   float foo [[user(locn0)]];
@@ -167,6 +171,8 @@
 
   ASSERT_TRUE(td.Determine()) << td.error();
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitEntryPointData(func)) << gen.error();
   EXPECT_EQ(gen.result(), R"(struct main_in {
   float foo [[user(locn0)]];
@@ -213,6 +219,8 @@
 
   ASSERT_TRUE(td.Determine()) << td.error();
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitEntryPointData(func)) << gen.error();
   EXPECT_EQ(gen.result(), R"(struct main_out {
   float foo [[color(0)]];
@@ -256,6 +264,8 @@
 
   ASSERT_TRUE(td.Determine()) << td.error();
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_FALSE(gen.EmitEntryPointData(func)) << gen.error();
   EXPECT_EQ(gen.error(), R"(invalid location variable for pipeline stage)");
 }
@@ -294,6 +304,8 @@
 
   ASSERT_TRUE(td.Determine()) << td.error();
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_FALSE(gen.EmitEntryPointData(func)) << gen.error();
   EXPECT_EQ(gen.error(), R"(invalid location variable for pipeline stage)");
 }
@@ -337,6 +349,8 @@
 
   ASSERT_TRUE(td.Determine()) << td.error();
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitEntryPointData(func)) << gen.error();
   EXPECT_EQ(gen.result(), R"(struct main_out {
   float depth [[depth(any)]];
diff --git a/src/writer/msl/generator_impl_function_test.cc b/src/writer/msl/generator_impl_function_test.cc
index 0ad50d3..80aefa2 100644
--- a/src/writer/msl/generator_impl_function_test.cc
+++ b/src/writer/msl/generator_impl_function_test.cc
@@ -63,6 +63,9 @@
                     ast::FunctionDecorationList{});
 
   mod->AddFunction(func);
+
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.Generate()) << gen.error();
@@ -83,6 +86,9 @@
                     ast::FunctionDecorationList{});
 
   mod->AddFunction(func);
+
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.Generate()) << gen.error();
@@ -107,6 +113,9 @@
                     ast::FunctionDecorationList{});
 
   mod->AddFunction(func);
+
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.Generate()) << gen.error();
@@ -129,6 +138,8 @@
 
   ASSERT_TRUE(td.Determine()) << td.error();
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.Generate()) << gen.error();
   EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
 
@@ -167,6 +178,8 @@
 
   ASSERT_TRUE(td.Determine()) << td.error();
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.Generate()) << gen.error();
   EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
 
@@ -214,6 +227,8 @@
 
   ASSERT_TRUE(td.Determine()) << td.error();
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.Generate()) << gen.error();
   EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
 
@@ -267,6 +282,8 @@
 
   ASSERT_TRUE(td.Determine()) << td.error();
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.Generate()) << gen.error();
   EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
 
@@ -310,6 +327,8 @@
 
   ASSERT_TRUE(td.Determine()) << td.error();
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.Generate()) << gen.error();
   EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
 
@@ -358,6 +377,9 @@
   mod->AddFunction(func);
 
   ASSERT_TRUE(td.Determine()) << td.error();
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.Generate()) << gen.error();
   EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
 
@@ -410,6 +432,8 @@
 
   ASSERT_TRUE(td.Determine()) << td.error();
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.Generate()) << gen.error();
   EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
 
@@ -475,6 +499,8 @@
 
   ASSERT_TRUE(td.Determine()) << td.error();
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.Generate()) << gen.error();
   EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
 
@@ -538,6 +564,8 @@
 
   ASSERT_TRUE(td.Determine()) << td.error();
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.Generate()) << gen.error();
   EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
 
@@ -603,6 +631,9 @@
   mod->AddFunction(func_1);
 
   ASSERT_TRUE(td.Determine()) << td.error();
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.Generate()) << gen.error();
   EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
 
@@ -664,6 +695,9 @@
   mod->AddFunction(func);
 
   ASSERT_TRUE(td.Determine()) << td.error();
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.Generate()) << gen.error();
   EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
 
@@ -726,6 +760,8 @@
 
   ASSERT_TRUE(td.Determine()) << td.error();
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.Generate()) << gen.error();
   EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
 
@@ -796,6 +832,8 @@
 
   ASSERT_TRUE(td.Determine()) << td.error();
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.Generate()) << gen.error();
   EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
 
@@ -846,6 +884,9 @@
   mod->AddFunction(func_1);
 
   ASSERT_TRUE(td.Determine()) << td.error();
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.Generate()) << gen.error();
   EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
 
@@ -875,6 +916,8 @@
 
   mod->AddFunction(func);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.Generate()) << gen.error();
   EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
 
@@ -896,6 +939,9 @@
                     ast::FunctionDecorationList{});
 
   mod->AddFunction(func);
+
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.Generate()) << gen.error();
@@ -977,6 +1023,8 @@
 
   ASSERT_TRUE(td.Determine()) << td.error();
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.Generate()) << gen.error();
   EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
 
diff --git a/src/writer/msl/generator_impl_identifier_test.cc b/src/writer/msl/generator_impl_identifier_test.cc
index ab3279a..af19be1 100644
--- a/src/writer/msl/generator_impl_identifier_test.cc
+++ b/src/writer/msl/generator_impl_identifier_test.cc
@@ -27,12 +27,18 @@
 
 TEST_F(MslGeneratorImplTest, EmitIdentifierExpression) {
   auto* i = Expr("foo");
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitExpression(i)) << gen.error();
   EXPECT_EQ(gen.result(), "foo");
 }
 
 TEST_F(MslGeneratorImplTest, EmitIdentifierExpression_Single_WithCollision) {
   auto* i = Expr("virtual");
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitExpression(i)) << gen.error();
   EXPECT_EQ(gen.result(), "virtual_tint_0");
 }
diff --git a/src/writer/msl/generator_impl_if_test.cc b/src/writer/msl/generator_impl_if_test.cc
index 7a42ac0..b1167a3 100644
--- a/src/writer/msl/generator_impl_if_test.cc
+++ b/src/writer/msl/generator_impl_if_test.cc
@@ -35,6 +35,8 @@
   });
   auto* i = create<ast::IfStatement>(cond, body, ast::ElseStatementList{});
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(i)) << gen.error();
@@ -60,6 +62,8 @@
           create<ast::ElseStatement>(else_cond, else_body),
       });
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(i)) << gen.error();
@@ -86,6 +90,8 @@
           create<ast::ElseStatement>(nullptr, else_body),
       });
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(i)) << gen.error();
@@ -119,6 +125,8 @@
           create<ast::ElseStatement>(nullptr, else_body_2),
       });
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(i)) << gen.error();
diff --git a/src/writer/msl/generator_impl_import_test.cc b/src/writer/msl/generator_impl_import_test.cc
index e123331..49688a3 100644
--- a/src/writer/msl/generator_impl_import_test.cc
+++ b/src/writer/msl/generator_impl_import_test.cc
@@ -55,6 +55,8 @@
   // The call type determination will set the intrinsic data for the ident
   ASSERT_TRUE(td.DetermineResultType(call)) << td.error();
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_EQ(
       gen.generate_builtin_name(call->func()->As<ast::IdentifierExpression>()),
       std::string("metal::") + param.msl_name);
@@ -89,6 +91,8 @@
   auto* expr = Call("abs", 1);
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitCall(expr)) << gen.error();
   EXPECT_EQ(gen.result(), R"(metal::abs(1))");
 }
@@ -99,6 +103,9 @@
   auto* expr = Call(param.name, 1.0f, 2.0f);
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitCall(expr)) << gen.error();
   EXPECT_EQ(gen.result(),
             std::string("metal::") + param.msl_name + "(1.0f, 2.0f)");
@@ -120,6 +127,9 @@
   auto* expr =
       Call(param.name, vec3<f32>(1.f, 2.f, 3.f), vec3<f32>(4.f, 5.f, 6.f));
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitCall(expr)) << gen.error();
   EXPECT_EQ(gen.result(), std::string("metal::") + param.msl_name +
                               "(float3(1.0f, 2.0f, 3.0f), "
@@ -135,6 +145,9 @@
 
   auto* expr = Call(param.name, 1, 2);
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitCall(expr)) << gen.error();
   EXPECT_EQ(gen.result(), std::string("metal::") + param.msl_name + "(1, 2)");
 }
@@ -149,6 +162,9 @@
 
   auto* expr = Call(param.name, 1.f, 2.f, 3.f);
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitCall(expr)) << gen.error();
   EXPECT_EQ(gen.result(),
             std::string("metal::") + param.msl_name + "(1.0f, 2.0f, 3.0f)");
@@ -168,6 +184,9 @@
 
   auto* expr = Call(param.name, 1, 2, 3);
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitCall(expr)) << gen.error();
   EXPECT_EQ(gen.result(),
             std::string("metal::") + param.msl_name + "(1, 2, 3)");
@@ -186,6 +205,9 @@
   // Register the global
   ASSERT_TRUE(td.Determine()) << td.error();
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitCall(expr)) << gen.error();
   EXPECT_EQ(gen.result(), std::string("metal::determinant(var)"));
 }
diff --git a/src/writer/msl/generator_impl_intrinsic_test.cc b/src/writer/msl/generator_impl_intrinsic_test.cc
index 41fa96e..652d6ce 100644
--- a/src/writer/msl/generator_impl_intrinsic_test.cc
+++ b/src/writer/msl/generator_impl_intrinsic_test.cc
@@ -40,6 +40,9 @@
 using MslIntrinsicTest = TestParamHelper<IntrinsicData>;
 TEST_P(MslIntrinsicTest, Emit) {
   auto param = GetParam();
+
+  GeneratorImpl& gen = Build();
+
   EXPECT_EQ(gen.generate_intrinsic_name(param.intrinsic), param.msl_name);
 }
 INSTANTIATE_TEST_SUITE_P(
@@ -66,6 +69,8 @@
                     IntrinsicData{ast::Intrinsic::kSelect, "select"}));
 
 TEST_F(MslGeneratorImplTest, Intrinsic_Bad_Name) {
+  GeneratorImpl& gen = Build();
+
   EXPECT_EQ(gen.generate_intrinsic_name(ast::Intrinsic::kNone), "");
 }
 
@@ -80,6 +85,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(call)) << td.error();
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
   ASSERT_TRUE(gen.EmitExpression(call)) << gen.error();
   EXPECT_EQ(gen.result(), "  dot(param1, param2)");
diff --git a/src/writer/msl/generator_impl_intrinsic_texture_test.cc b/src/writer/msl/generator_impl_intrinsic_texture_test.cc
index 4767626..a2ac3e4 100644
--- a/src/writer/msl/generator_impl_intrinsic_texture_test.cc
+++ b/src/writer/msl/generator_impl_intrinsic_texture_test.cc
@@ -22,6 +22,7 @@
 #include "src/type/sampled_texture_type.h"
 #include "src/type_determiner.h"
 #include "src/writer/msl/generator_impl.h"
+#include "src/writer/msl/test_helper.h"
 
 namespace tint {
 namespace writer {
@@ -305,17 +306,11 @@
 }  // NOLINT - Ignore the length of this function
 
 class MslGeneratorIntrinsicTextureTest
-    : public ast::BuilderWithModule,
-      public testing::TestWithParam<ast::intrinsic::test::TextureOverloadCase> {
+    : public TestParamHelper<ast::intrinsic::test::TextureOverloadCase> {
  protected:
   void OnVariableBuilt(ast::Variable* var) override {
     td.RegisterVariableForTesting(var);
   }
-
-  /// The type determiner
-  TypeDeterminer td{mod};
-  /// The generator
-  GeneratorImpl gen{mod};
 };
 
 TEST_P(MslGeneratorIntrinsicTextureTest, Call) {
@@ -330,6 +325,8 @@
   ASSERT_TRUE(td.Determine()) << td.error();
   ASSERT_TRUE(td.DetermineResultType(call)) << td.error();
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitExpression(call)) << gen.error();
 
   auto expected = expected_texture_overload(param.overload);
diff --git a/src/writer/msl/generator_impl_loop_test.cc b/src/writer/msl/generator_impl_loop_test.cc
index d7f13ab..7c42a84 100644
--- a/src/writer/msl/generator_impl_loop_test.cc
+++ b/src/writer/msl/generator_impl_loop_test.cc
@@ -41,6 +41,8 @@
   });
   auto* l = create<ast::LoopStatement>(body, nullptr);
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(l)) << gen.error();
@@ -59,6 +61,8 @@
   });
   auto* l = create<ast::LoopStatement>(body, continuing);
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(l)) << gen.error();
@@ -95,6 +99,8 @@
 
   auto* outer = create<ast::LoopStatement>(body, continuing);
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(outer)) << gen.error();
@@ -155,10 +161,13 @@
   auto* continuing = create<ast::BlockStatement>(ast::StatementList{
       create<ast::AssignmentStatement>(Expr("lhs"), Expr("rhs")),
   });
-  gen.increment_indent();
 
   auto* outer = create<ast::LoopStatement>(body, continuing);
 
+  GeneratorImpl& gen = Build();
+
+  gen.increment_indent();
+
   ASSERT_TRUE(gen.EmitStatement(outer)) << gen.error();
   EXPECT_EQ(gen.result(), R"(  {
     bool tint_msl_is_first_1 = true;
diff --git a/src/writer/msl/generator_impl_member_accessor_test.cc b/src/writer/msl/generator_impl_member_accessor_test.cc
index f1b8644..e1fdeaf 100644
--- a/src/writer/msl/generator_impl_member_accessor_test.cc
+++ b/src/writer/msl/generator_impl_member_accessor_test.cc
@@ -31,6 +31,8 @@
 TEST_F(MslGeneratorImplTest, EmitExpression_MemberAccessor) {
   auto* expr = MemberAccessor("str", "mem");
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitExpression(expr)) << gen.error();
   EXPECT_EQ(gen.result(), "str.mem");
 }
diff --git a/src/writer/msl/generator_impl_module_constant_test.cc b/src/writer/msl/generator_impl_module_constant_test.cc
index d251dc6..1b7022a 100644
--- a/src/writer/msl/generator_impl_module_constant_test.cc
+++ b/src/writer/msl/generator_impl_module_constant_test.cc
@@ -20,10 +20,10 @@
 #include "src/ast/float_literal.h"
 #include "src/ast/module.h"
 #include "src/ast/scalar_constructor_expression.h"
-#include "src/type/array_type.h"
-#include "src/type/f32_type.h"
 #include "src/ast/type_constructor_expression.h"
 #include "src/ast/variable.h"
+#include "src/type/array_type.h"
+#include "src/type/f32_type.h"
 #include "src/writer/msl/generator_impl.h"
 #include "src/writer/msl/test_helper.h"
 
@@ -39,6 +39,8 @@
       Const("pos", ast::StorageClass::kNone, ty.array<f32, 3>(),
             array<f32, 3>(1.f, 2.f, 3.f), ast::VariableDecorationList{});
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitProgramConstVariable(var)) << gen.error();
   EXPECT_EQ(gen.result(), "constant float pos[3] = {1.0f, 2.0f, 3.0f};\n");
 }
@@ -49,6 +51,8 @@
                         create<ast::ConstantIdDecoration>(23),
                     });
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitProgramConstVariable(var)) << gen.error();
   EXPECT_EQ(gen.result(), "constant float pos [[function_constant(23)]];\n");
 }
diff --git a/src/writer/msl/generator_impl_return_test.cc b/src/writer/msl/generator_impl_return_test.cc
index e017d6a..f881498 100644
--- a/src/writer/msl/generator_impl_return_test.cc
+++ b/src/writer/msl/generator_impl_return_test.cc
@@ -31,6 +31,9 @@
 
 TEST_F(MslGeneratorImplTest, Emit_Return) {
   auto* r = create<ast::ReturnStatement>();
+
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(r)) << gen.error();
@@ -39,6 +42,9 @@
 
 TEST_F(MslGeneratorImplTest, Emit_ReturnWithValue) {
   auto* r = create<ast::ReturnStatement>(Expr("expr"));
+
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(r)) << gen.error();
diff --git a/src/writer/msl/generator_impl_switch_test.cc b/src/writer/msl/generator_impl_switch_test.cc
index 8123138..435a1fd 100644
--- a/src/writer/msl/generator_impl_switch_test.cc
+++ b/src/writer/msl/generator_impl_switch_test.cc
@@ -52,6 +52,9 @@
   body.push_back(def);
 
   auto* s = create<ast::SwitchStatement>(Expr("cond"), body);
+
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(s)) << gen.error();
diff --git a/src/writer/msl/generator_impl_test.cc b/src/writer/msl/generator_impl_test.cc
index 69de899..42c1514 100644
--- a/src/writer/msl/generator_impl_test.cc
+++ b/src/writer/msl/generator_impl_test.cc
@@ -55,6 +55,8 @@
            });
   mod->AddFunction(func);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.Generate()) << gen.error();
   EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
 
@@ -66,17 +68,24 @@
 }
 
 TEST_F(MslGeneratorImplTest, InputStructName) {
+  GeneratorImpl& gen = Build();
+
   ASSERT_EQ(gen.generate_name("func_main_in"), "func_main_in");
 }
 
 TEST_F(MslGeneratorImplTest, InputStructName_ConflictWithExisting) {
+  GeneratorImpl& gen = Build();
+
   gen.namer_for_testing()->NameFor("func_main_out");
   ASSERT_EQ(gen.generate_name("func_main_out"), "func_main_out_0");
 }
 
 TEST_F(MslGeneratorImplTest, NameConflictWith_InputStructName) {
+  auto* ident = Expr("func_main_in");
+  GeneratorImpl& gen = Build();
+
   ASSERT_EQ(gen.generate_name("func_main_in"), "func_main_in");
-  ASSERT_TRUE(gen.EmitIdentifier(Expr("func_main_in")));
+  ASSERT_TRUE(gen.EmitIdentifier(ident));
   EXPECT_EQ(gen.result(), "func_main_in_0");
 }
 
@@ -92,6 +101,8 @@
 TEST_P(MslBuiltinConversionTest, Emit) {
   auto params = GetParam();
 
+  GeneratorImpl& gen = Build();
+
   EXPECT_EQ(gen.builtin_to_attribute(params.builtin),
             std::string(params.attribute_name));
 }
@@ -113,31 +124,45 @@
 
 TEST_F(MslGeneratorImplTest, calculate_alignment_size_alias) {
   auto* alias = ty.alias("a", ty.f32);
+  GeneratorImpl& gen = Build();
+
   EXPECT_EQ(4u, gen.calculate_alignment_size(alias));
 }
 
 TEST_F(MslGeneratorImplTest, calculate_alignment_size_array) {
+  GeneratorImpl& gen = Build();
+
   EXPECT_EQ(4u * 4u, gen.calculate_alignment_size(ty.array<f32, 4>()));
 }
 
 TEST_F(MslGeneratorImplTest, calculate_alignment_size_bool) {
+  GeneratorImpl& gen = Build();
+
   EXPECT_EQ(1u, gen.calculate_alignment_size(ty.bool_));
 }
 
 TEST_F(MslGeneratorImplTest, calculate_alignment_size_f32) {
+  GeneratorImpl& gen = Build();
+
   EXPECT_EQ(4u, gen.calculate_alignment_size(ty.f32));
 }
 
 TEST_F(MslGeneratorImplTest, calculate_alignment_size_i32) {
+  GeneratorImpl& gen = Build();
+
   EXPECT_EQ(4u, gen.calculate_alignment_size(ty.i32));
 }
 
 TEST_F(MslGeneratorImplTest, calculate_alignment_size_matrix) {
+  GeneratorImpl& gen = Build();
+
   EXPECT_EQ(4u * 3u * 2u, gen.calculate_alignment_size(ty.mat3x2<f32>()));
 }
 
 TEST_F(MslGeneratorImplTest, calculate_alignment_size_pointer) {
   type::Pointer ptr(ty.bool_, ast::StorageClass::kPrivate);
+  GeneratorImpl& gen = Build();
+
   EXPECT_EQ(0u, gen.calculate_alignment_size(&ptr));
 }
 
@@ -149,6 +174,9 @@
       ast::StructDecorationList{});
 
   auto* s = ty.struct_("S", str);
+
+  GeneratorImpl& gen = Build();
+
   EXPECT_EQ(132u, gen.calculate_alignment_size(s));
 }
 
@@ -168,10 +196,15 @@
       ast::StructDecorationList{});
 
   auto* outer_s = ty.struct_("Outer", outer_str);
+
+  GeneratorImpl& gen = Build();
+
   EXPECT_EQ(80u, gen.calculate_alignment_size(outer_s));
 }
 
 TEST_F(MslGeneratorImplTest, calculate_alignment_size_u32) {
+  GeneratorImpl& gen = Build();
+
   EXPECT_EQ(4u, gen.calculate_alignment_size(ty.u32));
 }
 
@@ -188,6 +221,8 @@
   auto param = GetParam();
 
   type::Vector vec(ty.bool_, param.elements);
+  GeneratorImpl& gen = Build();
+
   EXPECT_EQ(param.byte_size, gen.calculate_alignment_size(&vec));
 }
 INSTANTIATE_TEST_SUITE_P(MslGeneratorImplTest,
@@ -201,6 +236,9 @@
   auto param = GetParam();
 
   type::Vector vec(ty.i32, param.elements);
+
+  GeneratorImpl& gen = Build();
+
   EXPECT_EQ(param.byte_size, gen.calculate_alignment_size(&vec));
 }
 INSTANTIATE_TEST_SUITE_P(MslGeneratorImplTest,
@@ -214,6 +252,8 @@
   auto param = GetParam();
 
   type::Vector vec(ty.u32, param.elements);
+  GeneratorImpl& gen = Build();
+
   EXPECT_EQ(param.byte_size, gen.calculate_alignment_size(&vec));
 }
 INSTANTIATE_TEST_SUITE_P(MslGeneratorImplTest,
@@ -227,6 +267,8 @@
   auto param = GetParam();
 
   type::Vector vec(ty.f32, param.elements);
+  GeneratorImpl& gen = Build();
+
   EXPECT_EQ(param.byte_size, gen.calculate_alignment_size(&vec));
 }
 INSTANTIATE_TEST_SUITE_P(MslGeneratorImplTest,
diff --git a/src/writer/msl/generator_impl_type_test.cc b/src/writer/msl/generator_impl_type_test.cc
index 8bc1146..74dcff6 100644
--- a/src/writer/msl/generator_impl_type_test.cc
+++ b/src/writer/msl/generator_impl_type_test.cc
@@ -49,17 +49,25 @@
 
 TEST_F(MslGeneratorImplTest, EmitType_Alias) {
   auto* alias = ty.alias("alias", ty.f32);
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(alias, "")) << gen.error();
   EXPECT_EQ(gen.result(), "alias");
 }
 
 TEST_F(MslGeneratorImplTest, EmitType_Alias_NameCollision) {
   auto* alias = ty.alias("bool", ty.f32);
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(alias, "")) << gen.error();
   EXPECT_EQ(gen.result(), "bool_tint_0");
 }
 
 TEST_F(MslGeneratorImplTest, EmitType_Array) {
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(ty.array<bool, 4>(), "ary")) << gen.error();
   EXPECT_EQ(gen.result(), "bool ary[4]");
 }
@@ -67,6 +75,9 @@
 TEST_F(MslGeneratorImplTest, EmitType_ArrayOfArray) {
   auto* a = ty.array<bool, 4>();
   auto* b = ty.array(a, 5);
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(b, "ary")) << gen.error();
   EXPECT_EQ(gen.result(), "bool ary[5][4]");
 }
@@ -76,6 +87,9 @@
   auto* a = ty.array<bool, 4>();
   auto* b = ty.array(a, 5);
   auto* c = ty.array(b, 0);
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(c, "ary")) << gen.error();
   EXPECT_EQ(gen.result(), "bool ary[5][4][1]");
 }
@@ -84,47 +98,66 @@
   auto* a = ty.array<bool, 4>();
   auto* b = ty.array(a, 5);
   auto* c = ty.array(b, 6);
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(c, "ary")) << gen.error();
   EXPECT_EQ(gen.result(), "bool ary[6][5][4]");
 }
 
 TEST_F(MslGeneratorImplTest, EmitType_Array_NameCollision) {
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(ty.array<bool, 4>(), "bool")) << gen.error();
   EXPECT_EQ(gen.result(), "bool bool_tint_0[4]");
 }
 
 TEST_F(MslGeneratorImplTest, EmitType_Array_WithoutName) {
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(ty.array<bool, 4>(), "")) << gen.error();
   EXPECT_EQ(gen.result(), "bool[4]");
 }
 
 TEST_F(MslGeneratorImplTest, EmitType_RuntimeArray) {
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(ty.array<bool, 1>(), "ary")) << gen.error();
   EXPECT_EQ(gen.result(), "bool ary[1]");
 }
 
 TEST_F(MslGeneratorImplTest, EmitType_RuntimeArray_NameCollision) {
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(ty.array<bool, 1>(), "discard_fragment"))
       << gen.error();
   EXPECT_EQ(gen.result(), "bool discard_fragment_tint_0[1]");
 }
 
 TEST_F(MslGeneratorImplTest, EmitType_Bool) {
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(ty.bool_, "")) << gen.error();
   EXPECT_EQ(gen.result(), "bool");
 }
 
 TEST_F(MslGeneratorImplTest, EmitType_F32) {
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(ty.f32, "")) << gen.error();
   EXPECT_EQ(gen.result(), "float");
 }
 
 TEST_F(MslGeneratorImplTest, EmitType_I32) {
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(ty.i32, "")) << gen.error();
   EXPECT_EQ(gen.result(), "int");
 }
 
 TEST_F(MslGeneratorImplTest, EmitType_Matrix) {
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(ty.mat2x3<f32>(), "")) << gen.error();
   EXPECT_EQ(gen.result(), "float2x3");
 }
@@ -133,6 +166,8 @@
 TEST_F(MslGeneratorImplTest, DISABLED_EmitType_Pointer) {
   type::Pointer p(ty.f32, ast::StorageClass::kWorkgroup);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(&p, "")) << gen.error();
   EXPECT_EQ(gen.result(), "float*");
 }
@@ -144,6 +179,9 @@
       ast::StructDecorationList{});
 
   auto* s = ty.struct_("S", str);
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(s, "")) << gen.error();
   EXPECT_EQ(gen.result(), "S");
 }
@@ -156,6 +194,8 @@
 
   auto* s = ty.struct_("S", str);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitStructType(s)) << gen.error();
   EXPECT_EQ(gen.result(), R"(struct S {
   int a;
@@ -174,6 +214,9 @@
       ast::StructDecorationList{});
 
   auto* s = ty.struct_("S", str);
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitStructType(s)) << gen.error();
   EXPECT_EQ(gen.result(), R"(struct S {
   int8_t pad_0[4];
@@ -192,6 +235,9 @@
       ast::StructDecorationList{});
 
   auto* s = ty.struct_("S", str);
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitStructType(s)) << gen.error();
   EXPECT_EQ(gen.result(), R"(struct S {
   int main_tint_0;
@@ -210,6 +256,9 @@
       decos);
 
   auto* s = ty.struct_("S", str);
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(s, "")) << gen.error();
   EXPECT_EQ(gen.result(), R"(struct {
   int a;
@@ -218,16 +267,22 @@
 }
 
 TEST_F(MslGeneratorImplTest, EmitType_U32) {
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(ty.u32, "")) << gen.error();
   EXPECT_EQ(gen.result(), "uint");
 }
 
 TEST_F(MslGeneratorImplTest, EmitType_Vector) {
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(ty.vec3<f32>(), "")) << gen.error();
   EXPECT_EQ(gen.result(), "float3");
 }
 
 TEST_F(MslGeneratorImplTest, EmitType_Void) {
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(ty.void_, "")) << gen.error();
   EXPECT_EQ(gen.result(), "void");
 }
@@ -235,6 +290,8 @@
 TEST_F(MslGeneratorImplTest, EmitType_Sampler) {
   type::Sampler sampler(type::SamplerKind::kSampler);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(&sampler, "")) << gen.error();
   EXPECT_EQ(gen.result(), "sampler");
 }
@@ -242,6 +299,8 @@
 TEST_F(MslGeneratorImplTest, EmitType_SamplerComparison) {
   type::Sampler sampler(type::SamplerKind::kComparisonSampler);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(&sampler, "")) << gen.error();
   EXPECT_EQ(gen.result(), "sampler");
 }
@@ -260,6 +319,8 @@
 
   type::DepthTexture s(params.dim);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(&s, "")) << gen.error();
   EXPECT_EQ(gen.result(), params.result);
 }
@@ -290,6 +351,8 @@
 
   type::SampledTexture s(params.dim, ty.f32);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(&s, "")) << gen.error();
   EXPECT_EQ(gen.result(), params.result);
 }
@@ -315,6 +378,8 @@
 TEST_F(MslGeneratorImplTest, Emit_TypeMultisampledTexture) {
   type::MultisampledTexture s(type::TextureDimension::k2d, ty.u32);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(&s, "")) << gen.error();
   EXPECT_EQ(gen.result(), "texture2d_ms<uint, access::sample>");
 }
@@ -338,6 +403,9 @@
                          &s);
 
   ASSERT_TRUE(td.DetermineStorageTextureSubtype(&s)) << td.error();
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(&ac, "")) << gen.error();
   EXPECT_EQ(gen.result(), params.result);
 }
diff --git a/src/writer/msl/generator_impl_unary_op_test.cc b/src/writer/msl/generator_impl_unary_op_test.cc
index c93bee2..3a689ca 100644
--- a/src/writer/msl/generator_impl_unary_op_test.cc
+++ b/src/writer/msl/generator_impl_unary_op_test.cc
@@ -39,6 +39,9 @@
 TEST_P(MslUnaryOpTest, Emit) {
   auto params = GetParam();
   auto* op = create<ast::UnaryOpExpression>(params.op, Expr("expr"));
+
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitExpression(op)) << gen.error();
   EXPECT_EQ(gen.result(), std::string(params.name) + "(expr)");
 }
diff --git a/src/writer/msl/generator_impl_variable_decl_statement_test.cc b/src/writer/msl/generator_impl_variable_decl_statement_test.cc
index 3da40f8..da4be9b 100644
--- a/src/writer/msl/generator_impl_variable_decl_statement_test.cc
+++ b/src/writer/msl/generator_impl_variable_decl_statement_test.cc
@@ -44,6 +44,8 @@
   auto* var = Var("a", ast::StorageClass::kNone, ty.f32);
   auto* stmt = create<ast::VariableDeclStatement>(var);
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(stmt)) << gen.error();
@@ -54,6 +56,8 @@
   auto* var = Const("a", ast::StorageClass::kNone, ty.f32);
   auto* stmt = create<ast::VariableDeclStatement>(var);
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(stmt)) << gen.error();
@@ -66,6 +70,8 @@
   auto* var = Var("a", ast::StorageClass::kNone, &ary);
   auto* stmt = create<ast::VariableDeclStatement>(var);
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(stmt)) << gen.error();
@@ -82,6 +88,8 @@
   auto* var = Var("a", ast::StorageClass::kNone, s);
   auto* stmt = create<ast::VariableDeclStatement>(var);
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(stmt)) << gen.error();
@@ -93,6 +101,8 @@
   auto* var = Var("a", ast::StorageClass::kFunction, ty.vec2<f32>());
   auto* stmt = create<ast::VariableDeclStatement>(var);
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(stmt)) << gen.error();
@@ -104,6 +114,8 @@
 
   auto* stmt = create<ast::VariableDeclStatement>(var);
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(stmt)) << gen.error();
@@ -114,6 +126,8 @@
   auto* var = Var("a", ast::StorageClass::kPrivate, ty.f32);
   auto* stmt = create<ast::VariableDeclStatement>(var);
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(stmt)) << gen.error();
@@ -125,6 +139,8 @@
                   ast::VariableDecorationList{});
   auto* stmt = create<ast::VariableDeclStatement>(var);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitStatement(stmt)) << gen.error();
   EXPECT_EQ(gen.result(), R"(float a = initializer;
 )");
@@ -137,6 +153,8 @@
                   ast::VariableDecorationList{});
   auto* stmt = create<ast::VariableDeclStatement>(var);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitStatement(stmt)) << gen.error();
   EXPECT_EQ(gen.result(), R"(float3 a = float3(0.0f);
 )");
diff --git a/src/writer/msl/test_helper.h b/src/writer/msl/test_helper.h
index 554e628..1d1f0d5 100644
--- a/src/writer/msl/test_helper.h
+++ b/src/writer/msl/test_helper.h
@@ -32,13 +32,26 @@
 template <typename BASE>
 class TestHelperBase : public BASE, public ast::BuilderWithModule {
  public:
-  TestHelperBase() : td(mod), gen(mod) {}
+  TestHelperBase() : td(mod) {}
   ~TestHelperBase() = default;
 
+  /// Builds and returns a GeneratorImpl from the module.
+  /// @note The generator is only built once. Multiple calls to Build() will
+  /// return the same GeneratorImpl without rebuilding.
+  /// @return the built generator
+  GeneratorImpl& Build() {
+    if (gen_) {
+      return *gen_;
+    }
+    gen_ = std::make_unique<GeneratorImpl>(mod);
+    return *gen_;
+  }
+
   /// The type determiner
   TypeDeterminer td;
-  /// The generator
-  GeneratorImpl gen;
+
+ private:
+  std::unique_ptr<GeneratorImpl> gen_;
 };
 using TestHelper = TestHelperBase<testing::Test>;
 
diff --git a/src/writer/spirv/binary_writer_test.cc b/src/writer/spirv/binary_writer_test.cc
index 68bb796..b69c72a 100644
--- a/src/writer/spirv/binary_writer_test.cc
+++ b/src/writer/spirv/binary_writer_test.cc
@@ -42,6 +42,8 @@
 }
 
 TEST_F(BinaryWriterTest, Float) {
+  spirv::Builder& b = Build();
+
   b.push_annot(spv::Op::OpKill, {Operand::Float(2.4f)});
   BinaryWriter bw;
   bw.WriteBuilder(&b);
@@ -54,6 +56,8 @@
 }
 
 TEST_F(BinaryWriterTest, Int) {
+  spirv::Builder& b = Build();
+
   b.push_annot(spv::Op::OpKill, {Operand::Int(2)});
   BinaryWriter bw;
   bw.WriteBuilder(&b);
@@ -64,6 +68,8 @@
 }
 
 TEST_F(BinaryWriterTest, String) {
+  spirv::Builder& b = Build();
+
   b.push_annot(spv::Op::OpKill, {Operand::String("my_string")});
   BinaryWriter bw;
   bw.WriteBuilder(&b);
@@ -87,6 +93,8 @@
 }
 
 TEST_F(BinaryWriterTest, String_Multiple4Length) {
+  spirv::Builder& b = Build();
+
   b.push_annot(spv::Op::OpKill, {Operand::String("mystring")});
   BinaryWriter bw;
   bw.WriteBuilder(&b);
diff --git a/src/writer/spirv/builder_accessor_expression_test.cc b/src/writer/spirv/builder_accessor_expression_test.cc
index 8159bff..5551098 100644
--- a/src/writer/spirv/builder_accessor_expression_test.cc
+++ b/src/writer/spirv/builder_accessor_expression_test.cc
@@ -55,10 +55,11 @@
   auto* idx_expr = Expr(1);
 
   auto* expr = IndexAccessor(ary, idx_expr);
-
   td.RegisterVariableForTesting(var);
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
 
@@ -97,6 +98,8 @@
   td.RegisterVariableForTesting(idx);
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
   ASSERT_TRUE(b.GenerateFunctionVariable(idx)) << b.error();
@@ -135,6 +138,8 @@
   td.RegisterVariableForTesting(var);
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
 
@@ -171,6 +176,8 @@
   td.RegisterVariableForTesting(var);
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
 
@@ -209,6 +216,8 @@
   td.RegisterVariableForTesting(var);
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
   EXPECT_EQ(b.GenerateAccessorExpression(expr), 15u);
@@ -255,6 +264,8 @@
   td.RegisterVariableForTesting(var);
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
 
@@ -302,6 +313,8 @@
   td.RegisterVariableForTesting(var);
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
 
@@ -352,6 +365,8 @@
   td.RegisterVariableForTesting(var);
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
 
@@ -401,6 +416,8 @@
   td.RegisterVariableForTesting(var);
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
 
@@ -456,6 +473,8 @@
   td.RegisterVariableForTesting(store);
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
   ASSERT_TRUE(b.GenerateFunctionVariable(store)) << b.error();
@@ -493,6 +512,8 @@
   td.RegisterVariableForTesting(var);
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
 
@@ -524,6 +545,8 @@
   td.RegisterVariableForTesting(var);
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
 
@@ -554,6 +577,8 @@
   td.RegisterVariableForTesting(var);
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
 
@@ -585,6 +610,8 @@
   td.RegisterVariableForTesting(var);
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
 
@@ -615,6 +642,8 @@
   td.RegisterVariableForTesting(var);
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
 
@@ -677,6 +706,8 @@
   td.RegisterVariableForTesting(var);
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
 
@@ -731,6 +762,8 @@
   ASSERT_TRUE(td.DetermineResultType(var->constructor())) << td.error();
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
   EXPECT_EQ(b.GenerateAccessorExpression(expr), 18u) << b.error();
@@ -774,6 +807,8 @@
   ASSERT_TRUE(td.DetermineResultType(var->constructor())) << td.error();
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
   EXPECT_EQ(b.GenerateAccessorExpression(expr), 8u) << b.error();
diff --git a/src/writer/spirv/builder_assign_test.cc b/src/writer/spirv/builder_assign_test.cc
index 040cac9..3c117e4 100644
--- a/src/writer/spirv/builder_assign_test.cc
+++ b/src/writer/spirv/builder_assign_test.cc
@@ -49,6 +49,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(assign)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
   ASSERT_FALSE(b.has_error()) << b.error();
@@ -63,7 +65,8 @@
 %5 = OpConstant %3 1
 )");
 
-  EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %1 %5
+  EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+            R"(OpStore %1 %5
 )");
 }
 
@@ -75,14 +78,16 @@
 
   ASSERT_TRUE(td.DetermineResultType(assign)) << td.error();
 
+  spirv::Builder& b = Build();
+
   EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
   ASSERT_FALSE(b.has_error()) << b.error();
 
   EXPECT_FALSE(b.GenerateAssignStatement(assign)) << b.error();
   EXPECT_TRUE(b.has_error());
-  EXPECT_EQ(
-      b.error(),
-      "Internal error: trying to add SPIR-V instruction 62 outside a function");
+  EXPECT_EQ(b.error(),
+            "Internal error: trying to add SPIR-V instruction 62 outside a "
+            "function");
 }
 
 TEST_F(BuilderTest, Assign_Var_ZeroConstructor) {
@@ -95,6 +100,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(assign)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
   ASSERT_FALSE(b.has_error()) << b.error();
@@ -109,7 +116,8 @@
 %1 = OpVariable %2 Output %5
 )");
 
-  EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %1 %5
+  EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+            R"(OpStore %1 %5
 )");
 }
 
@@ -122,6 +130,8 @@
   td.RegisterVariableForTesting(v);
   ASSERT_TRUE(td.DetermineResultType(assign)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
   ASSERT_FALSE(b.has_error()) << b.error();
@@ -157,6 +167,8 @@
   td.RegisterVariableForTesting(v);
   ASSERT_TRUE(td.DetermineResultType(assign)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
   ASSERT_FALSE(b.has_error()) << b.error();
@@ -174,7 +186,8 @@
 %8 = OpConstant %4 3
 %9 = OpConstantComposite %3 %6 %7 %8
 )");
-  EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %1 %9
+  EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+            R"(OpStore %1 %9
 )");
 }
 
@@ -199,6 +212,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(assign)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
   ASSERT_FALSE(b.has_error()) << b.error();
@@ -232,6 +247,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(assign)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
   ASSERT_FALSE(b.has_error()) << b.error();
@@ -249,7 +266,8 @@
 %8 = OpConstantComposite %3 %6 %6 %7
 )");
 
-  EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %1 %8
+  EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+            R"(OpStore %1 %8
 )");
 }
 
@@ -264,6 +282,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(assign)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
   ASSERT_FALSE(b.has_error()) << b.error();
@@ -299,6 +319,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(assign)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   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 8f2b5a8..66acd47 100644
--- a/src/writer/spirv/builder_binary_expression_test.cc
+++ b/src/writer/spirv/builder_binary_expression_test.cc
@@ -61,6 +61,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
 
   EXPECT_EQ(b.GenerateBinaryExpression(expr), 4u) << b.error();
@@ -71,6 +73,7 @@
   EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
             "%4 = " + param.name + " %1 %2 %3\n");
 }
+
 TEST_P(BinaryArithSignedIntegerTest, Vector) {
   auto param = GetParam();
 
@@ -81,6 +84,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
 
   EXPECT_EQ(b.GenerateBinaryExpression(expr), 5u) << b.error();
@@ -102,6 +107,8 @@
   td.RegisterVariableForTesting(var);
   EXPECT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
   EXPECT_EQ(b.GenerateBinaryExpression(expr), 7u) << b.error();
@@ -147,6 +154,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
 
   EXPECT_EQ(b.GenerateBinaryExpression(expr), 4u) << b.error();
@@ -167,6 +176,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
 
   EXPECT_EQ(b.GenerateBinaryExpression(expr), 5u) << b.error();
@@ -203,6 +214,8 @@
   auto* expr = create<ast::BinaryExpression>(param.op, lhs, rhs);
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
 
   EXPECT_EQ(b.GenerateBinaryExpression(expr), 4u) << b.error();
@@ -224,6 +237,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
 
   EXPECT_EQ(b.GenerateBinaryExpression(expr), 5u) << b.error();
@@ -255,6 +270,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
 
   EXPECT_EQ(b.GenerateBinaryExpression(expr), 4u) << b.error();
@@ -277,6 +294,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
 
   EXPECT_EQ(b.GenerateBinaryExpression(expr), 5u) << b.error();
@@ -312,6 +331,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
 
   EXPECT_EQ(b.GenerateBinaryExpression(expr), 4u) << b.error();
@@ -334,6 +355,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
 
   EXPECT_EQ(b.GenerateBinaryExpression(expr), 5u) << b.error();
@@ -369,6 +392,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
 
   EXPECT_EQ(b.GenerateBinaryExpression(expr), 4u) << b.error();
@@ -391,6 +416,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
 
   EXPECT_EQ(b.GenerateBinaryExpression(expr), 5u) << b.error();
@@ -424,10 +451,13 @@
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
 
   EXPECT_EQ(b.GenerateBinaryExpression(expr), 5u) << b.error();
-  EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+  EXPECT_EQ(DumpInstructions(b.types()),
+            R"(%2 = OpTypeFloat 32
 %1 = OpTypeVector %2 3
 %3 = OpConstant %2 1
 %4 = OpConstantComposite %1 %3 %3 %3
@@ -445,10 +475,13 @@
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
 
   EXPECT_EQ(b.GenerateBinaryExpression(expr), 5u) << b.error();
-  EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 32
+  EXPECT_EQ(DumpInstructions(b.types()),
+            R"(%1 = OpTypeFloat 32
 %2 = OpConstant %1 1
 %3 = OpTypeVector %1 3
 %4 = OpConstantComposite %3 %2 %2 %2
@@ -465,11 +498,14 @@
                                              Expr("mat"), Expr(1.f));
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
 
   EXPECT_EQ(b.GenerateBinaryExpression(expr), 8u) << b.error();
-  EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeFloat 32
+  EXPECT_EQ(DumpInstructions(b.types()),
+            R"(%5 = OpTypeFloat 32
 %4 = OpTypeVector %5 3
 %3 = OpTypeMatrix %4 3
 %2 = OpTypePointer Function %3
@@ -491,11 +527,14 @@
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
 
   EXPECT_EQ(b.GenerateBinaryExpression(expr), 8u) << b.error();
-  EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeFloat 32
+  EXPECT_EQ(DumpInstructions(b.types()),
+            R"(%5 = OpTypeFloat 32
 %4 = OpTypeVector %5 3
 %3 = OpTypeMatrix %4 3
 %2 = OpTypePointer Function %3
@@ -519,11 +558,14 @@
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
 
   EXPECT_EQ(b.GenerateBinaryExpression(expr), 9u) << b.error();
-  EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeFloat 32
+  EXPECT_EQ(DumpInstructions(b.types()),
+            R"(%5 = OpTypeFloat 32
 %4 = OpTypeVector %5 3
 %3 = OpTypeMatrix %4 3
 %2 = OpTypePointer Function %3
@@ -548,11 +590,14 @@
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
 
   EXPECT_EQ(b.GenerateBinaryExpression(expr), 9u) << b.error();
-  EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeFloat 32
+  EXPECT_EQ(DumpInstructions(b.types()),
+            R"(%5 = OpTypeFloat 32
 %4 = OpTypeVector %5 3
 %3 = OpTypeMatrix %4 3
 %2 = OpTypePointer Function %3
@@ -575,11 +620,14 @@
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
 
   EXPECT_EQ(b.GenerateBinaryExpression(expr), 8u) << b.error();
-  EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeFloat 32
+  EXPECT_EQ(DumpInstructions(b.types()),
+            R"(%5 = OpTypeFloat 32
 %4 = OpTypeVector %5 3
 %3 = OpTypeMatrix %4 3
 %2 = OpTypePointer Function %3
@@ -604,11 +652,14 @@
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   b.GenerateLabel(b.next_id());
 
   EXPECT_EQ(b.GenerateBinaryExpression(expr), 12u) << b.error();
-  EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 1
+  EXPECT_EQ(DumpInstructions(b.types()),
+            R"(%2 = OpTypeInt 32 1
 %3 = OpConstant %2 1
 %4 = OpConstant %2 2
 %6 = OpTypeBool
@@ -642,6 +693,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   b.GenerateLabel(b.next_id());
 
@@ -682,6 +735,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   b.GenerateLabel(b.next_id());
 
@@ -720,6 +775,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   b.GenerateLabel(b.next_id());
 
@@ -757,11 +814,14 @@
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   b.GenerateLabel(b.next_id());
 
   EXPECT_EQ(b.GenerateBinaryExpression(expr), 12u) << b.error();
-  EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 1
+  EXPECT_EQ(DumpInstructions(b.types()),
+            R"(%2 = OpTypeInt 32 1
 %3 = OpConstant %2 1
 %4 = OpConstant %2 2
 %6 = OpTypeBool
@@ -795,6 +855,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   b.GenerateLabel(b.next_id());
 
diff --git a/src/writer/spirv/builder_bitcast_expression_test.cc b/src/writer/spirv/builder_bitcast_expression_test.cc
index 2b0ba00..33a717a 100644
--- a/src/writer/spirv/builder_bitcast_expression_test.cc
+++ b/src/writer/spirv/builder_bitcast_expression_test.cc
@@ -36,6 +36,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(bitcast)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_EQ(b.GenerateBitcastExpression(bitcast), 1u);
 
@@ -53,6 +55,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(bitcast)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_EQ(b.GenerateBitcastExpression(bitcast), 1u);
 
diff --git a/src/writer/spirv/builder_block_test.cc b/src/writer/spirv/builder_block_test.cc
index e751849..9421765 100644
--- a/src/writer/spirv/builder_block_test.cc
+++ b/src/writer/spirv/builder_block_test.cc
@@ -49,6 +49,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(outer)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   ASSERT_FALSE(b.has_error()) << b.error();
 
@@ -68,7 +70,8 @@
 %6 = OpVariable %2 Function %4
 )");
 
-  EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %1 %5
+  EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+            R"(OpStore %1 %5
 OpStore %6 %7
 OpStore %1 %8
 )");
diff --git a/src/writer/spirv/builder_call_test.cc b/src/writer/spirv/builder_call_test.cc
index e1cf83f..cde2e03 100644
--- a/src/writer/spirv/builder_call_test.cc
+++ b/src/writer/spirv/builder_call_test.cc
@@ -57,6 +57,8 @@
   ASSERT_TRUE(td.DetermineFunction(a_func)) << td.error();
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   ASSERT_TRUE(b.GenerateFunction(a_func)) << b.error();
   ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
 
@@ -106,6 +108,8 @@
   ASSERT_TRUE(td.DetermineFunction(a_func)) << td.error();
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   ASSERT_TRUE(b.GenerateFunction(a_func)) << b.error();
   ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
 
diff --git a/src/writer/spirv/builder_constructor_expression_test.cc b/src/writer/spirv/builder_constructor_expression_test.cc
index a4f675a..d539145 100644
--- a/src/writer/spirv/builder_constructor_expression_test.cc
+++ b/src/writer/spirv/builder_constructor_expression_test.cc
@@ -52,6 +52,8 @@
 TEST_F(SpvBuilderConstructorTest, Const) {
   auto* c = Expr(42.2f);
 
+  spirv::Builder& b = Build();
+
   EXPECT_EQ(b.GenerateConstructorExpression(nullptr, c, true), 2u);
   ASSERT_FALSE(b.has_error()) << b.error();
 
@@ -65,6 +67,8 @@
 
   EXPECT_TRUE(td.DetermineResultType(t)) << td.error();
 
+  spirv::Builder& b = Build();
+
   EXPECT_EQ(b.GenerateExpression(t), 0u);
   EXPECT_TRUE(b.has_error()) << b.error();
   EXPECT_EQ(b.error(),
@@ -77,6 +81,8 @@
 
   EXPECT_TRUE(td.DetermineResultType(t)) << td.error();
 
+  spirv::Builder& b = Build();
+
   EXPECT_EQ(b.GenerateConstructorExpression(nullptr, t, true), 5u);
   ASSERT_FALSE(b.has_error()) << b.error();
 
@@ -93,6 +99,8 @@
 
   EXPECT_TRUE(td.DetermineResultType(t)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
 
   EXPECT_EQ(b.GenerateExpression(t), 7u);
@@ -119,6 +127,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(cast)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_EQ(b.GenerateExpression(cast), 1u);
 
@@ -138,6 +148,8 @@
 
   EXPECT_TRUE(td.DetermineResultType(t)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
 
@@ -165,6 +177,8 @@
 
   EXPECT_TRUE(td.DetermineResultType(t)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
 
   EXPECT_EQ(b.GenerateExpression(t), 7u);
@@ -191,6 +205,8 @@
 
   EXPECT_TRUE(td.DetermineResultType(t)) << td.error();
 
+  spirv::Builder& b = Build();
+
   EXPECT_EQ(b.GenerateConstructorExpression(nullptr, t, true), 0u);
   EXPECT_TRUE(b.has_error());
   EXPECT_EQ(b.error(), R"(constructor must be a constant expression)");
@@ -201,6 +217,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(cast)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
 
   EXPECT_EQ(b.GenerateExpression(cast), 3u);
@@ -217,6 +235,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(cast)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_EQ(b.GenerateExpression(cast), 3u);
 
@@ -231,6 +251,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(cast)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_EQ(b.GenerateExpression(cast), 3u);
 
@@ -245,6 +267,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(cast)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_EQ(b.GenerateExpression(cast), 3u);
 
@@ -259,6 +283,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(cast)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_EQ(b.GenerateExpression(cast), 4u);
 
@@ -275,6 +301,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(cast)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_EQ(b.GenerateExpression(cast), 5u);
 
@@ -291,6 +319,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(cast)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_EQ(b.GenerateExpression(cast), 4u);
 
@@ -306,6 +336,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(cast)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_EQ(b.GenerateExpression(cast), 8u);
 
@@ -327,6 +359,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(cast)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_EQ(b.GenerateExpression(cast), 8u);
 
@@ -349,6 +383,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(cast)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_EQ(b.GenerateExpression(cast), 5u);
 
@@ -365,6 +401,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(cast)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_EQ(b.GenerateExpression(cast), 4u);
 
@@ -380,6 +418,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(cast)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_EQ(b.GenerateExpression(cast), 8u);
 
@@ -401,6 +441,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(cast)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_EQ(b.GenerateExpression(cast), 8u);
 
@@ -422,6 +464,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(cast)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_EQ(b.GenerateExpression(cast), 8u);
 
@@ -443,6 +487,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(cast)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_EQ(b.GenerateExpression(cast), 10u);
 
@@ -466,6 +512,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(cast)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_EQ(b.GenerateExpression(cast), 9u);
 
@@ -488,6 +536,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(cast)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_EQ(b.GenerateExpression(cast), 9u);
 
@@ -511,6 +561,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(cast)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_EQ(b.GenerateExpression(cast), 5u);
 
@@ -527,6 +579,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(cast)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_EQ(b.GenerateConstructorExpression(nullptr, cast, true), 5u);
 
@@ -542,6 +596,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(cast)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_EQ(b.GenerateConstructorExpression(nullptr, cast, true), 5u);
 
@@ -557,6 +613,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(cast)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_EQ(b.GenerateConstructorExpression(nullptr, cast, true), 5u);
 
@@ -572,6 +630,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(cast)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_EQ(b.GenerateConstructorExpression(nullptr, cast, true), 11u);
 
@@ -594,6 +654,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(cast)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_EQ(b.GenerateConstructorExpression(nullptr, cast, true), 11u);
 
@@ -616,6 +678,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(cast)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_EQ(b.GenerateConstructorExpression(nullptr, cast, true), 11u);
 
@@ -638,6 +702,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(cast)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_EQ(b.GenerateConstructorExpression(nullptr, cast, true), 11u);
 
@@ -660,6 +726,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(cast)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_EQ(b.GenerateConstructorExpression(nullptr, cast, true), 11u);
 
@@ -682,6 +750,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(cast)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_EQ(b.GenerateConstructorExpression(nullptr, cast, true), 13u);
 
@@ -706,6 +776,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(cast)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_EQ(b.GenerateConstructorExpression(nullptr, cast, true), 13u);
 
@@ -730,6 +802,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(cast)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_EQ(b.GenerateConstructorExpression(nullptr, cast, true), 13u);
 
@@ -754,6 +828,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(cast)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_EQ(b.GenerateExpression(cast), 6u);
 
@@ -772,6 +848,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(cast)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_EQ(b.GenerateExpression(cast), 6u);
 
@@ -790,6 +868,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(cast)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_EQ(b.GenerateExpression(cast), 6u);
 
@@ -808,6 +888,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(cast)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_EQ(b.GenerateExpression(cast), 6u);
 
@@ -827,6 +909,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(cast)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_EQ(b.GenerateExpression(cast), 6u);
 
@@ -846,6 +930,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(cast)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_EQ(b.GenerateExpression(cast), 6u);
 
@@ -864,6 +950,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(cast)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_EQ(b.GenerateExpression(cast), 6u);
 
@@ -883,6 +971,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(cast)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_EQ(b.GenerateExpression(cast), 6u);
 
@@ -902,6 +992,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(cast)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_EQ(b.GenerateExpression(cast), 6u);
 
@@ -919,6 +1011,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(cast)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_EQ(b.GenerateExpression(cast), 6u);
 
@@ -937,6 +1031,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(cast)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_EQ(b.GenerateExpression(cast), 8u);
 
@@ -963,6 +1059,8 @@
   auto* t = Construct(s_type, 2.0f, vec3<f32>(2.0f, 2.0f, 2.0f));
   EXPECT_TRUE(td.DetermineResultType(t)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
 
   EXPECT_EQ(b.GenerateExpression(t), 6u);
@@ -982,6 +1080,8 @@
 
   EXPECT_TRUE(td.DetermineResultType(t)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
 
   EXPECT_EQ(b.GenerateExpression(t), 2u);
@@ -997,6 +1097,8 @@
 
   EXPECT_TRUE(td.DetermineResultType(t)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
 
   EXPECT_EQ(b.GenerateExpression(t), 2u);
@@ -1012,6 +1114,8 @@
 
   EXPECT_TRUE(td.DetermineResultType(t)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
 
   EXPECT_EQ(b.GenerateExpression(t), 2u);
@@ -1027,6 +1131,8 @@
 
   EXPECT_TRUE(td.DetermineResultType(t)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
 
   EXPECT_EQ(b.GenerateExpression(t), 2u);
@@ -1042,6 +1148,8 @@
 
   EXPECT_TRUE(td.DetermineResultType(t)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
 
   EXPECT_EQ(b.GenerateExpression(t), 3u);
@@ -1058,6 +1166,8 @@
 
   EXPECT_TRUE(td.DetermineResultType(t)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
 
   EXPECT_EQ(b.GenerateExpression(t), 4u);
@@ -1075,6 +1185,8 @@
 
   EXPECT_TRUE(td.DetermineResultType(t)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
 
   EXPECT_EQ(b.GenerateExpression(t), 5u);
@@ -1098,6 +1210,8 @@
   auto* t = Construct(s_type);
   EXPECT_TRUE(td.DetermineResultType(t)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
 
   EXPECT_EQ(b.GenerateExpression(t), 3u);
@@ -1114,6 +1228,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(cast)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_EQ(b.GenerateExpression(cast), 1u);
 
@@ -1131,6 +1247,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(cast)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_EQ(b.GenerateExpression(cast), 1u);
 
@@ -1148,6 +1266,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(cast)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_EQ(b.GenerateExpression(cast), 1u);
 
@@ -1165,6 +1285,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(cast)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_EQ(b.GenerateExpression(cast), 1u);
 
@@ -1182,6 +1304,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(cast)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_EQ(b.GenerateExpression(cast), 1u);
 
@@ -1199,6 +1323,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(cast)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_EQ(b.GenerateExpression(cast), 1u);
 
@@ -1218,6 +1344,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(cast)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
   EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
@@ -1243,6 +1371,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(cast)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
   EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
@@ -1268,6 +1398,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(cast)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
   EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
@@ -1293,6 +1425,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(cast)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
   EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
@@ -1318,6 +1452,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(cast)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
   EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
@@ -1343,6 +1479,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(cast)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
   EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
@@ -1368,6 +1506,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(t)) << td.error();
 
+  spirv::Builder& b = Build();
+
   EXPECT_TRUE(b.is_constructor_const(t, true));
   EXPECT_FALSE(b.has_error());
 }
@@ -1382,6 +1522,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(t)) << td.error();
 
+  spirv::Builder& b = Build();
+
   EXPECT_FALSE(b.is_constructor_const(t, true));
   EXPECT_TRUE(b.has_error());
   EXPECT_EQ(b.error(), "constructor must be a constant expression");
@@ -1396,6 +1538,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(t)) << td.error();
 
+  spirv::Builder& b = Build();
+
   EXPECT_TRUE(b.is_constructor_const(t, true));
   EXPECT_FALSE(b.has_error());
 }
@@ -1408,6 +1552,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(t)) << td.error();
 
+  spirv::Builder& b = Build();
+
   EXPECT_FALSE(b.is_constructor_const(t, true));
   EXPECT_FALSE(b.has_error());
 }
@@ -1420,6 +1566,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(t)) << td.error();
 
+  spirv::Builder& b = Build();
+
   EXPECT_FALSE(b.is_constructor_const(t, true));
   EXPECT_FALSE(b.has_error());
 }
@@ -1432,6 +1580,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(t)) << td.error();
 
+  spirv::Builder& b = Build();
+
   EXPECT_TRUE(b.is_constructor_const(t, false));
   EXPECT_FALSE(b.has_error());
 }
@@ -1447,6 +1597,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(t)) << td.error();
 
+  spirv::Builder& b = Build();
+
   EXPECT_FALSE(b.is_constructor_const(t, false));
   EXPECT_FALSE(b.has_error());
 }
@@ -1463,6 +1615,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(t)) << td.error();
 
+  spirv::Builder& b = Build();
+
   EXPECT_TRUE(b.is_constructor_const(t, false));
   EXPECT_FALSE(b.has_error());
 }
@@ -1475,6 +1629,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(t)) << td.error();
 
+  spirv::Builder& b = Build();
+
   EXPECT_FALSE(b.is_constructor_const(t, false));
   EXPECT_FALSE(b.has_error());
 }
@@ -1486,6 +1642,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(t)) << td.error();
 
+  spirv::Builder& b = Build();
+
   EXPECT_FALSE(b.is_constructor_const(t, false));
   EXPECT_FALSE(b.has_error());
 }
@@ -1495,6 +1653,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(t)) << td.error();
 
+  spirv::Builder& b = Build();
+
   EXPECT_FALSE(b.is_constructor_const(t, false));
   EXPECT_FALSE(b.has_error());
 }
@@ -1510,6 +1670,8 @@
   auto* t = Construct(s_type, 2.f, vec3<f32>(2.f, 2.f, 2.f));
   ASSERT_TRUE(td.DetermineResultType(t)) << td.error();
 
+  spirv::Builder& b = Build();
+
   EXPECT_TRUE(b.is_constructor_const(t, false));
   EXPECT_FALSE(b.has_error());
 }
@@ -1531,6 +1693,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(t)) << td.error();
 
+  spirv::Builder& b = Build();
+
   EXPECT_FALSE(b.is_constructor_const(t, false));
   EXPECT_FALSE(b.has_error());
 }
diff --git a/src/writer/spirv/builder_discard_test.cc b/src/writer/spirv/builder_discard_test.cc
index 6031a4c..9445023 100644
--- a/src/writer/spirv/builder_discard_test.cc
+++ b/src/writer/spirv/builder_discard_test.cc
@@ -29,6 +29,8 @@
 TEST_F(BuilderTest, Discard) {
   auto* expr = create<ast::DiscardStatement>();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_EQ(b.GenerateStatement(expr), 1u) << b.error();
   EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpKill
diff --git a/src/writer/spirv/builder_format_conversion_test.cc b/src/writer/spirv/builder_format_conversion_test.cc
index 0c9df47..0ad7697 100644
--- a/src/writer/spirv/builder_format_conversion_test.cc
+++ b/src/writer/spirv/builder_format_conversion_test.cc
@@ -36,6 +36,8 @@
 TEST_P(ImageFormatConversionTest, ImageFormatConversion) {
   auto param = GetParam();
 
+  spirv::Builder& b = Build();
+
   EXPECT_EQ(b.convert_image_format_to_spv(param.ast_format), param.spv_format);
 
   if (param.extended_format) {
diff --git a/src/writer/spirv/builder_function_decoration_test.cc b/src/writer/spirv/builder_function_decoration_test.cc
index 16189d6..ef9e7ec 100644
--- a/src/writer/spirv/builder_function_decoration_test.cc
+++ b/src/writer/spirv/builder_function_decoration_test.cc
@@ -43,6 +43,8 @@
                create<ast::StageDecoration>(ast::PipelineStage::kVertex),
            });
 
+  spirv::Builder& b = Build();
+
   ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
   EXPECT_EQ(DumpInstructions(b.entry_points()),
             R"(OpEntryPoint Vertex %3 "main"
@@ -66,6 +68,8 @@
                         create<ast::StageDecoration>(params.stage),
                     });
 
+  spirv::Builder& b = Build();
+
   ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
 
   auto preamble = b.entry_points();
@@ -96,14 +100,16 @@
   auto* v_out = Var("my_out", ast::StorageClass::kOutput, ty.f32);
   auto* v_wg = Var("my_wg", ast::StorageClass::kWorkgroup, ty.f32);
 
-  EXPECT_TRUE(b.GenerateGlobalVariable(v_in)) << b.error();
-  EXPECT_TRUE(b.GenerateGlobalVariable(v_out)) << b.error();
-  EXPECT_TRUE(b.GenerateGlobalVariable(v_wg)) << b.error();
-
   mod->AddGlobalVariable(v_in);
   mod->AddGlobalVariable(v_out);
   mod->AddGlobalVariable(v_wg);
 
+  spirv::Builder& b = Build();
+
+  EXPECT_TRUE(b.GenerateGlobalVariable(v_in)) << b.error();
+  EXPECT_TRUE(b.GenerateGlobalVariable(v_out)) << b.error();
+  EXPECT_TRUE(b.GenerateGlobalVariable(v_wg)) << b.error();
+
   ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
   EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "my_in"
 OpName %4 "my_out"
@@ -143,20 +149,22 @@
   auto* v_out = Var("my_out", ast::StorageClass::kOutput, ty.f32);
   auto* v_wg = Var("my_wg", ast::StorageClass::kWorkgroup, ty.f32);
 
+  mod->AddGlobalVariable(v_in);
+  mod->AddGlobalVariable(v_out);
+  mod->AddGlobalVariable(v_wg);
+
   td.RegisterVariableForTesting(v_in);
   td.RegisterVariableForTesting(v_out);
   td.RegisterVariableForTesting(v_wg);
 
   ASSERT_TRUE(td.DetermineFunction(func)) << td.error();
 
+  spirv::Builder& b = Build();
+
   EXPECT_TRUE(b.GenerateGlobalVariable(v_in)) << b.error();
   EXPECT_TRUE(b.GenerateGlobalVariable(v_out)) << b.error();
   EXPECT_TRUE(b.GenerateGlobalVariable(v_wg)) << b.error();
 
-  mod->AddGlobalVariable(v_in);
-  mod->AddGlobalVariable(v_out);
-  mod->AddGlobalVariable(v_wg);
-
   ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
   EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "my_in"
 OpName %4 "my_out"
@@ -186,6 +194,8 @@
                create<ast::StageDecoration>(ast::PipelineStage::kFragment),
            });
 
+  spirv::Builder& b = Build();
+
   ASSERT_TRUE(b.GenerateExecutionModes(func, 3)) << b.error();
   EXPECT_EQ(DumpInstructions(b.execution_modes()),
             R"(OpExecutionMode %3 OriginUpperLeft
@@ -199,6 +209,8 @@
                create<ast::StageDecoration>(ast::PipelineStage::kCompute),
            });
 
+  spirv::Builder& b = Build();
+
   ASSERT_TRUE(b.GenerateExecutionModes(func, 3)) << b.error();
   EXPECT_EQ(DumpInstructions(b.execution_modes()),
             R"(OpExecutionMode %3 LocalSize 1 1 1
@@ -213,6 +225,8 @@
                create<ast::StageDecoration>(ast::PipelineStage::kCompute),
            });
 
+  spirv::Builder& b = Build();
+
   ASSERT_TRUE(b.GenerateExecutionModes(func, 3)) << b.error();
   EXPECT_EQ(DumpInstructions(b.execution_modes()),
             R"(OpExecutionMode %3 LocalSize 2 4 6
@@ -232,6 +246,8 @@
                create<ast::StageDecoration>(ast::PipelineStage::kFragment),
            });
 
+  spirv::Builder& b = Build();
+
   ASSERT_TRUE(b.GenerateFunction(func1)) << b.error();
   ASSERT_TRUE(b.GenerateFunction(func2)) << b.error();
   EXPECT_EQ(DumpBuilder(b),
@@ -271,6 +287,8 @@
 
   func->add_referenced_module_variable(fragdepth);
 
+  spirv::Builder& b = Build();
+
   ASSERT_TRUE(b.GenerateExecutionModes(func, 3)) << b.error();
   EXPECT_EQ(DumpInstructions(b.execution_modes()),
             R"(OpExecutionMode %3 DepthReplacing
diff --git a/src/writer/spirv/builder_function_test.cc b/src/writer/spirv/builder_function_test.cc
index cc04b1c..3796661 100644
--- a/src/writer/spirv/builder_function_test.cc
+++ b/src/writer/spirv/builder_function_test.cc
@@ -49,6 +49,8 @@
   auto* func = Func("a_func", {}, ty.void_, ast::StatementList{},
                     ast::FunctionDecorationList{});
 
+  spirv::Builder& b = Build();
+
   ASSERT_TRUE(b.GenerateFunction(func));
   EXPECT_EQ(DumpBuilder(b), R"(OpName %3 "a_func"
 %2 = OpTypeVoid
@@ -67,6 +69,8 @@
                     },
                     ast::FunctionDecorationList{});
 
+  spirv::Builder& b = Build();
+
   ASSERT_TRUE(b.GenerateFunction(func));
   EXPECT_EQ(DumpBuilder(b), R"(OpName %3 "a_func"
 %2 = OpTypeVoid
@@ -87,6 +91,9 @@
                     ast::FunctionDecorationList{});
 
   ASSERT_TRUE(td.DetermineFunction(func)) << td.error();
+
+  spirv::Builder& b = Build();
+
   ASSERT_TRUE(b.GenerateGlobalVariable(var_a)) << b.error();
   ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
   EXPECT_EQ(DumpBuilder(b), R"(OpName %1 "a"
@@ -112,6 +119,8 @@
                     },
                     ast::FunctionDecorationList{});
 
+  spirv::Builder& b = Build();
+
   ASSERT_TRUE(b.GenerateFunction(func));
   EXPECT_EQ(DumpBuilder(b), R"(OpName %3 "a_func"
 %2 = OpTypeVoid
@@ -135,6 +144,8 @@
   td.RegisterVariableForTesting(func->params()[1]);
   EXPECT_TRUE(td.DetermineFunction(func));
 
+  spirv::Builder& b = Build();
+
   ASSERT_TRUE(b.GenerateFunction(func));
   EXPECT_EQ(DumpBuilder(b), R"(OpName %4 "a_func"
 OpName %5 "a"
@@ -159,6 +170,8 @@
                     },
                     ast::FunctionDecorationList{});
 
+  spirv::Builder& b = Build();
+
   ASSERT_TRUE(b.GenerateFunction(func));
   EXPECT_EQ(DumpBuilder(b), R"(OpName %3 "a_func"
 %2 = OpTypeVoid
@@ -174,6 +187,8 @@
   auto* func = Func("a_func", {}, ty.void_, ast::StatementList{},
                     ast::FunctionDecorationList{});
 
+  spirv::Builder& b = Build();
+
   ASSERT_TRUE(b.GenerateFunction(func));
   EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
@@ -186,6 +201,8 @@
   auto* func2 = Func("b_func", {}, ty.void_, ast::StatementList{},
                      ast::FunctionDecorationList{});
 
+  spirv::Builder& b = Build();
+
   ASSERT_TRUE(b.GenerateFunction(func1));
   ASSERT_TRUE(b.GenerateFunction(func2));
   EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
@@ -266,6 +283,8 @@
 
   ASSERT_TRUE(td.Determine()) << td.error();
 
+  spirv::Builder& b = Build();
+
   ASSERT_TRUE(b.Build());
   EXPECT_EQ(DumpBuilder(b), R"(OpCapability Shader
 OpMemoryModel Logical GLSL450
diff --git a/src/writer/spirv/builder_function_variable_test.cc b/src/writer/spirv/builder_function_variable_test.cc
index 21bccc5..05ff914 100644
--- a/src/writer/spirv/builder_function_variable_test.cc
+++ b/src/writer/spirv/builder_function_variable_test.cc
@@ -25,13 +25,13 @@
 #include "src/ast/scalar_constructor_expression.h"
 #include "src/ast/storage_class.h"
 #include "src/ast/struct.h"
+#include "src/ast/type_constructor_expression.h"
+#include "src/ast/variable.h"
+#include "src/ast/variable_decoration.h"
 #include "src/type/access_control_type.h"
 #include "src/type/f32_type.h"
 #include "src/type/struct_type.h"
 #include "src/type/vector_type.h"
-#include "src/ast/type_constructor_expression.h"
-#include "src/ast/variable.h"
-#include "src/ast/variable_decoration.h"
 #include "src/type_determiner.h"
 #include "src/writer/spirv/builder.h"
 #include "src/writer/spirv/spv_dump.h"
@@ -47,6 +47,8 @@
 TEST_F(BuilderTest, FunctionVar_NoStorageClass) {
   auto* v = Var("var", ast::StorageClass::kNone, ty.f32);
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_TRUE(b.GenerateFunctionVariable(v)) << b.error();
   EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
@@ -70,6 +72,8 @@
                 ast::VariableDecorationList{});
   td.RegisterVariableForTesting(v);
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_TRUE(b.GenerateFunctionVariable(v)) << b.error();
   ASSERT_FALSE(b.has_error()) << b.error();
@@ -87,7 +91,8 @@
   EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
             R"(%6 = OpVariable %7 Function %8
 )");
-  EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %6 %5
+  EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+            R"(OpStore %6 %5
 )");
 }
 
@@ -99,6 +104,8 @@
                 ast::VariableDecorationList{});
 
   td.RegisterVariableForTesting(v);
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_TRUE(b.GenerateFunctionVariable(v)) << b.error();
   ASSERT_FALSE(b.has_error()) << b.error();
@@ -137,6 +144,8 @@
   ASSERT_TRUE(td.DetermineResultType(v->constructor())) << td.error();
   ASSERT_TRUE(td.DetermineResultType(v2->constructor())) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_TRUE(b.GenerateFunctionVariable(v)) << b.error();
   EXPECT_TRUE(b.GenerateFunctionVariable(v2)) << b.error();
@@ -176,6 +185,8 @@
   ASSERT_TRUE(td.DetermineResultType(v->constructor())) << td.error();
   ASSERT_TRUE(td.DetermineResultType(v2->constructor())) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_TRUE(b.GenerateFunctionVariable(v)) << b.error();
   EXPECT_TRUE(b.GenerateFunctionVariable(v2)) << b.error();
@@ -209,6 +220,8 @@
 
   td.RegisterVariableForTesting(v);
 
+  spirv::Builder& b = Build();
+
   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 cb0184c..ec0838a 100644
--- a/src/writer/spirv/builder_global_variable_test.cc
+++ b/src/writer/spirv/builder_global_variable_test.cc
@@ -51,6 +51,9 @@
 
 TEST_F(BuilderTest, GlobalVar_NoStorageClass) {
   auto* v = Var("var", ast::StorageClass::kNone, ty.f32);
+
+  spirv::Builder& b = Build();
+
   EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
   EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
 )");
@@ -63,6 +66,9 @@
 
 TEST_F(BuilderTest, GlobalVar_WithStorageClass) {
   auto* v = Var("var", ast::StorageClass::kOutput, ty.f32);
+
+  spirv::Builder& b = Build();
+
   EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
   EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
 )");
@@ -75,6 +81,9 @@
 
 TEST_F(BuilderTest, GlobalVar_WithStorageClass_Input) {
   auto* v = Var("var", ast::StorageClass::kInput, ty.f32);
+
+  spirv::Builder& b = Build();
+
   EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
   EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
 )");
@@ -92,6 +101,8 @@
                 ast::VariableDecorationList{});
   td.RegisterVariableForTesting(v);
 
+  spirv::Builder& b = Build();
+
   EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
   ASSERT_FALSE(b.has_error()) << b.error();
 
@@ -115,6 +126,8 @@
                   ast::VariableDecorationList{});
   td.RegisterVariableForTesting(v);
 
+  spirv::Builder& b = Build();
+
   EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
   ASSERT_FALSE(b.has_error()) << b.error();
 
@@ -136,6 +149,8 @@
                   ast::VariableDecorationList{});
   td.RegisterVariableForTesting(v);
 
+  spirv::Builder& b = Build();
+
   EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
   ASSERT_FALSE(b.has_error()) << b.error();
 
@@ -157,6 +172,8 @@
                   ast::VariableDecorationList{});
   td.RegisterVariableForTesting(v);
 
+  spirv::Builder& b = Build();
+
   EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
   ASSERT_FALSE(b.has_error()) << b.error();
 
@@ -182,6 +199,8 @@
                     create<ast::LocationDecoration>(5),
                 });
 
+  spirv::Builder& b = Build();
+
   EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
   EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
 )");
@@ -201,6 +220,8 @@
                     create<ast::GroupDecoration>(3),
                 });
 
+  spirv::Builder& b = Build();
+
   EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
   EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
 )");
@@ -220,6 +241,8 @@
                     create<ast::BuiltinDecoration>(ast::Builtin::kPosition),
                 });
 
+  spirv::Builder& b = Build();
+
   EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
   EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
 )");
@@ -238,6 +261,8 @@
                     create<ast::ConstantIdDecoration>(1200),
                 });
 
+  spirv::Builder& b = Build();
+
   EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
   EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %3 "var"
 )");
@@ -256,6 +281,8 @@
                     create<ast::ConstantIdDecoration>(1200),
                 });
 
+  spirv::Builder& b = Build();
+
   EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
   EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
 )");
@@ -274,6 +301,8 @@
                     create<ast::ConstantIdDecoration>(0),
                 });
 
+  spirv::Builder& b = Build();
+
   EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
   EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %3 "var"
 )");
@@ -292,6 +321,8 @@
                     create<ast::ConstantIdDecoration>(0),
                 });
 
+  spirv::Builder& b = Build();
+
   EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
   EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
 )");
@@ -310,6 +341,8 @@
                     create<ast::ConstantIdDecoration>(0),
                 });
 
+  spirv::Builder& b = Build();
+
   EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
   EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
 )");
@@ -328,6 +361,8 @@
                     create<ast::ConstantIdDecoration>(0),
                 });
 
+  spirv::Builder& b = Build();
+
   EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
   EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
 )");
@@ -351,6 +386,8 @@
 using BuiltinDataTest = TestParamHelper<BuiltinData>;
 TEST_P(BuiltinDataTest, Convert) {
   auto params = GetParam();
+  spirv::Builder& b = Build();
+
   EXPECT_EQ(b.ConvertBuiltin(params.builtin), params.result);
 }
 INSTANTIATE_TEST_SUITE_P(
@@ -387,6 +424,9 @@
   type::AccessControl ac{ast::AccessControl::kReadOnly, A};
 
   auto* var = Var("b", ast::StorageClass::kStorage, &ac);
+
+  spirv::Builder& b = Build();
+
   EXPECT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
 
   EXPECT_EQ(DumpInstructions(b.annots()), R"(OpMemberDecorate %3 0 NonWritable
@@ -417,6 +457,9 @@
   auto* B = ty.alias("B", A);
   type::AccessControl ac{ast::AccessControl::kReadOnly, B};
   auto* var = Var("b", ast::StorageClass::kStorage, &ac);
+
+  spirv::Builder& b = Build();
+
   EXPECT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
 
   EXPECT_EQ(DumpInstructions(b.annots()), R"(OpMemberDecorate %3 0 NonWritable
@@ -445,6 +488,9 @@
   type::AccessControl ac{ast::AccessControl::kReadOnly, A};
   auto* B = ty.alias("B", &ac);
   auto* var = Var("b", ast::StorageClass::kStorage, B);
+
+  spirv::Builder& b = Build();
+
   EXPECT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
 
   EXPECT_EQ(DumpInstructions(b.annots()), R"(OpMemberDecorate %3 0 NonWritable
@@ -475,10 +521,14 @@
 
   auto* var_b = Var("b", ast::StorageClass::kStorage, &read);
   auto* var_c = Var("c", ast::StorageClass::kStorage, &rw);
+
+  spirv::Builder& b = Build();
+
   EXPECT_TRUE(b.GenerateGlobalVariable(var_b)) << b.error();
   EXPECT_TRUE(b.GenerateGlobalVariable(var_c)) << b.error();
 
-  EXPECT_EQ(DumpInstructions(b.annots()), R"(OpMemberDecorate %3 0 NonWritable
+  EXPECT_EQ(DumpInstructions(b.annots()),
+            R"(OpMemberDecorate %3 0 NonWritable
 )");
   EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %3 "A"
 OpMemberName %3 0 "a"
@@ -507,6 +557,9 @@
   type::AccessControl ac(ast::AccessControl::kReadOnly, &type);
 
   auto* var_a = Var("a", ast::StorageClass::kUniformConstant, &ac);
+
+  spirv::Builder& b = Build();
+
   EXPECT_TRUE(b.GenerateGlobalVariable(var_a)) << b.error();
 
   EXPECT_EQ(DumpInstructions(b.annots()), R"(OpDecorate %1 NonWritable
@@ -528,6 +581,9 @@
   type::AccessControl ac(ast::AccessControl::kWriteOnly, &type);
 
   auto* var_a = Var("a", ast::StorageClass::kUniformConstant, &ac);
+
+  spirv::Builder& b = Build();
+
   EXPECT_TRUE(b.GenerateGlobalVariable(var_a)) << b.error();
 
   EXPECT_EQ(DumpInstructions(b.annots()), R"(OpDecorate %1 NonReadable
@@ -551,16 +607,20 @@
 
   type::AccessControl type_a(ast::AccessControl::kReadOnly, &st);
   auto* var_a = Var("a", ast::StorageClass::kUniformConstant, &type_a);
-  EXPECT_TRUE(b.GenerateGlobalVariable(var_a)) << b.error();
 
   type::AccessControl type_b(ast::AccessControl::kWriteOnly, &st);
   auto* var_b = Var("b", ast::StorageClass::kUniformConstant, &type_b);
+
+  spirv::Builder& b = Build();
+
+  EXPECT_TRUE(b.GenerateGlobalVariable(var_a)) << b.error();
   EXPECT_TRUE(b.GenerateGlobalVariable(var_b)) << b.error();
 
   EXPECT_EQ(DumpInstructions(b.annots()), R"(OpDecorate %1 NonWritable
 OpDecorate %5 NonReadable
 )");
-  // There must only be one OpTypeImage declaration with the same arguments
+  // There must only be one OpTypeImage declaration with the same
+  // arguments
   EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeInt 32 0
 %3 = OpTypeImage %4 2D 0 0 0 2 R32ui
 %2 = OpTypePointer UniformConstant %3
diff --git a/src/writer/spirv/builder_ident_expression_test.cc b/src/writer/spirv/builder_ident_expression_test.cc
index 083abb7..deb112c 100644
--- a/src/writer/spirv/builder_ident_expression_test.cc
+++ b/src/writer/spirv/builder_ident_expression_test.cc
@@ -45,6 +45,11 @@
                   ast::VariableDecorationList{});
   td.RegisterVariableForTesting(v);
 
+  auto* expr = Expr("var");
+  ASSERT_TRUE(td.DetermineResultType(expr));
+
+  spirv::Builder& b = Build();
+
   EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
   ASSERT_FALSE(b.has_error()) << b.error();
 
@@ -55,8 +60,6 @@
 %5 = OpConstantComposite %1 %3 %3 %4
 )");
 
-  auto* expr = Expr("var");
-  ASSERT_TRUE(td.DetermineResultType(expr));
   EXPECT_EQ(b.GenerateIdentifierExpression(expr), 5u);
 }
 
@@ -64,6 +67,11 @@
   auto* v = Var("var", ast::StorageClass::kOutput, ty.f32);
   td.RegisterVariableForTesting(v);
 
+  auto* expr = Expr("var");
+  ASSERT_TRUE(td.DetermineResultType(expr));
+
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
   EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
@@ -74,8 +82,6 @@
 %1 = OpVariable %2 Output %4
 )");
 
-  auto* expr = Expr("var");
-  ASSERT_TRUE(td.DetermineResultType(expr));
   EXPECT_EQ(b.GenerateIdentifierExpression(expr), 1u);
 }
 
@@ -87,6 +93,11 @@
                   ast::VariableDecorationList{});
   td.RegisterVariableForTesting(v);
 
+  auto* expr = Expr("var");
+  ASSERT_TRUE(td.DetermineResultType(expr));
+
+  spirv::Builder& b = Build();
+
   EXPECT_TRUE(b.GenerateFunctionVariable(v)) << b.error();
   ASSERT_FALSE(b.has_error()) << b.error();
 
@@ -97,8 +108,6 @@
 %5 = OpConstantComposite %1 %3 %3 %4
 )");
 
-  auto* expr = Expr("var");
-  ASSERT_TRUE(td.DetermineResultType(expr));
   EXPECT_EQ(b.GenerateIdentifierExpression(expr), 5u);
 }
 
@@ -106,6 +115,11 @@
   auto* v = Var("var", ast::StorageClass::kNone, ty.f32);
   td.RegisterVariableForTesting(v);
 
+  auto* expr = Expr("var");
+  ASSERT_TRUE(td.DetermineResultType(expr));
+
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_TRUE(b.GenerateFunctionVariable(v)) << b.error();
   EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
@@ -120,8 +134,6 @@
             R"(%1 = OpVariable %2 Function %4
 )");
 
-  auto* expr = Expr("var");
-  ASSERT_TRUE(td.DetermineResultType(expr));
   EXPECT_EQ(b.GenerateIdentifierExpression(expr), 1u);
 }
 
@@ -132,6 +144,8 @@
   auto* expr = Add("var", "var");
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
 
@@ -157,6 +171,8 @@
   auto* expr = Add("var", "var");
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   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 f826e0a..8e32317 100644
--- a/src/writer/spirv/builder_if_test.cc
+++ b/src/writer/spirv/builder_if_test.cc
@@ -51,6 +51,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
 
   EXPECT_TRUE(b.GenerateIfStatement(expr)) << b.error();
@@ -78,6 +80,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   EXPECT_FALSE(b.GenerateIfStatement(expr)) << b.error();
   EXPECT_TRUE(b.has_error());
   EXPECT_EQ(b.error(),
@@ -99,6 +103,8 @@
   td.RegisterVariableForTesting(var);
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
 
@@ -142,6 +148,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
 
@@ -191,6 +199,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
 
@@ -255,6 +265,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
 
@@ -323,6 +335,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
 
   EXPECT_TRUE(b.GenerateLoopStatement(expr)) << b.error();
@@ -371,6 +385,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
 
   EXPECT_TRUE(b.GenerateLoopStatement(expr)) << b.error();
@@ -419,6 +435,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
 
   EXPECT_TRUE(b.GenerateLoopStatement(expr)) << b.error();
@@ -467,6 +485,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
 
   EXPECT_TRUE(b.GenerateLoopStatement(expr)) << b.error();
@@ -505,6 +525,8 @@
       create<ast::IfStatement>(Expr(true), if_body, ast::ElseStatementList{});
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
 
   EXPECT_TRUE(b.GenerateIfStatement(expr)) << b.error();
@@ -532,6 +554,8 @@
       create<ast::IfStatement>(Expr(true), if_body, ast::ElseStatementList{});
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
 
   EXPECT_TRUE(b.GenerateIfStatement(expr)) << b.error();
@@ -562,6 +586,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
 
diff --git a/src/writer/spirv/builder_intrinsic_test.cc b/src/writer/spirv/builder_intrinsic_test.cc
index d1d7a8d..8becf79 100644
--- a/src/writer/spirv/builder_intrinsic_test.cc
+++ b/src/writer/spirv/builder_intrinsic_test.cc
@@ -45,26 +45,17 @@
 #include "src/type_determiner.h"
 #include "src/writer/spirv/builder.h"
 #include "src/writer/spirv/spv_dump.h"
+#include "src/writer/spirv/test_helper.h"
 
 namespace tint {
 namespace writer {
 namespace spirv {
 namespace {
 
-class IntrinsicBuilderTest : public ast::BuilderWithModule,
-                             public testing::Test {
- protected:
-  void OnVariableBuilt(ast::Variable* var) override {
-    td.RegisterVariableForTesting(var);
-  }
-
-  TypeDeterminer td{mod};
-  spirv::Builder b{mod};
-};
+using IntrinsicBuilderTest = TestHelper;
 
 template <typename T>
-class IntrinsicBuilderTestWithParam : public IntrinsicBuilderTest,
-                                      public testing::WithParamInterface<T> {};
+using IntrinsicBuilderTestWithParam = TestParamHelper<T>;
 
 struct IntrinsicData {
   std::string name;
@@ -84,6 +75,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
 
@@ -113,6 +106,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
 
@@ -137,6 +132,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
 
@@ -168,6 +165,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
 
@@ -191,6 +190,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
 
@@ -215,6 +216,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
 
@@ -238,6 +241,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
 
@@ -265,6 +270,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
 
@@ -291,6 +298,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
 
@@ -314,6 +323,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
 
@@ -356,6 +367,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateGlobalVariable(v3)) << b.error();
   ASSERT_TRUE(b.GenerateGlobalVariable(bool_v3)) << b.error();
@@ -386,23 +399,23 @@
   type::Sampler s(type::SamplerKind::kComparisonSampler);
   type::DepthTexture t(type::TextureDimension::k2d);
 
-  b.push_function(Function{});
-
   auto* tex = Var("texture", ast::StorageClass::kNone, &t);
-  ASSERT_TRUE(b.GenerateGlobalVariable(tex)) << b.error();
-
   auto* sampler = Var("sampler", ast::StorageClass::kNone, &s);
-  ASSERT_TRUE(b.GenerateGlobalVariable(sampler)) << b.error();
-
   auto* expr1 = Call("textureSampleCompare", "texture", "sampler",
                      vec2<f32>(1.0f, 2.0f), 2.0f);
-
   auto* expr2 = Call("textureSampleCompare", "texture", "sampler",
                      vec2<f32>(1.0f, 2.0f), 2.0f);
 
   EXPECT_TRUE(td.DetermineResultType(expr1)) << td.error();
   EXPECT_TRUE(td.DetermineResultType(expr2)) << td.error();
 
+  spirv::Builder& b = Build();
+
+  b.push_function(Function{});
+
+  ASSERT_TRUE(b.GenerateGlobalVariable(tex)) << b.error();
+  ASSERT_TRUE(b.GenerateGlobalVariable(sampler)) << b.error();
+
   EXPECT_EQ(b.GenerateExpression(expr1), 8u) << b.error();
   EXPECT_EQ(b.GenerateExpression(expr2), 18u) << b.error();
 
@@ -442,6 +455,8 @@
   auto* func = Func("a_func", ast::VariableList{}, ty.void_,
                     ast::StatementList{}, ast::FunctionDecorationList{});
 
+  spirv::Builder& b = Build();
+
   ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
   ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
 
@@ -475,6 +490,8 @@
   auto* func = Func("a_func", ast::VariableList{}, ty.void_,
                     ast::StatementList{}, ast::FunctionDecorationList{});
 
+  spirv::Builder& b = Build();
+
   ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
 
   EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error();
@@ -502,6 +519,8 @@
   auto* func = Func("a_func", ast::VariableList{}, ty.void_,
                     ast::StatementList{}, ast::FunctionDecorationList{});
 
+  spirv::Builder& b = Build();
+
   ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
 
   EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error();
@@ -555,6 +574,8 @@
   auto* func = Func("a_func", ast::VariableList{}, ty.void_,
                     ast::StatementList{}, ast::FunctionDecorationList{});
 
+  spirv::Builder& b = Build();
+
   ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
 
   EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error();
@@ -579,6 +600,8 @@
   auto* func = Func("a_func", ast::VariableList{}, ty.void_,
                     ast::StatementList{}, ast::FunctionDecorationList{});
 
+  spirv::Builder& b = Build();
+
   ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
 
   EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error();
@@ -605,6 +628,8 @@
   auto* func = Func("a_func", ast::VariableList{}, ty.void_,
                     ast::StatementList{}, ast::FunctionDecorationList{});
 
+  spirv::Builder& b = Build();
+
   ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
 
   EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error();
@@ -636,6 +661,8 @@
   auto* func = Func("a_func", ast::VariableList{}, ty.void_,
                     ast::StatementList{}, ast::FunctionDecorationList{});
 
+  spirv::Builder& b = Build();
+
   ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
 
   EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error();
@@ -664,6 +691,8 @@
   auto* func = Func("a_func", ast::VariableList{}, ty.void_,
                     ast::StatementList{}, ast::FunctionDecorationList{});
 
+  spirv::Builder& b = Build();
+
   ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
 
   EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error();
@@ -700,6 +729,8 @@
   auto* func = Func("a_func", ast::VariableList{}, ty.void_,
                     ast::StatementList{}, ast::FunctionDecorationList{});
 
+  spirv::Builder& b = Build();
+
   ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
 
   EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error();
@@ -725,6 +756,8 @@
   auto* func = Func("a_func", ast::VariableList{}, ty.void_,
                     ast::StatementList{}, ast::FunctionDecorationList{});
 
+  spirv::Builder& b = Build();
+
   ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
 
   EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error();
@@ -753,6 +786,8 @@
   auto* func = Func("a_func", ast::VariableList{}, ty.void_,
                     ast::StatementList{}, ast::FunctionDecorationList{});
 
+  spirv::Builder& b = Build();
+
   ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
 
   EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error();
@@ -783,6 +818,8 @@
   auto* func = Func("a_func", ast::VariableList{}, ty.void_,
                     ast::StatementList{}, ast::FunctionDecorationList{});
 
+  spirv::Builder& b = Build();
+
   ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
 
   EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error();
@@ -812,6 +849,8 @@
   auto* func = Func("a_func", ast::VariableList{}, ty.void_,
                     ast::StatementList{}, ast::FunctionDecorationList{});
 
+  spirv::Builder& b = Build();
+
   ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
 
   EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error();
@@ -852,6 +891,8 @@
   auto* func = Func("a_func", ast::VariableList{}, ty.void_,
                     ast::StatementList{}, ast::FunctionDecorationList{});
 
+  spirv::Builder& b = Build();
+
   ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
 
   EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error();
@@ -879,6 +920,8 @@
   auto* func = Func("a_func", ast::VariableList{}, ty.void_,
                     ast::StatementList{}, ast::FunctionDecorationList{});
 
+  spirv::Builder& b = Build();
+
   ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
 
   EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error();
@@ -913,6 +956,8 @@
   auto* func = Func("a_func", ast::VariableList{}, ty.void_,
                     ast::StatementList{}, ast::FunctionDecorationList{});
 
+  spirv::Builder& b = Build();
+
   ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
 
   EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error();
@@ -940,6 +985,8 @@
   auto* func = Func("a_func", ast::VariableList{}, ty.void_,
                     ast::StatementList{}, ast::FunctionDecorationList{});
 
+  spirv::Builder& b = Build();
+
   ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
 
   EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error();
@@ -974,6 +1021,8 @@
   auto* func = Func("a_func", ast::VariableList{}, ty.void_,
                     ast::StatementList{}, ast::FunctionDecorationList{});
 
+  spirv::Builder& b = Build();
+
   ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
 
   EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error();
@@ -1001,6 +1050,8 @@
   auto* func = Func("a_func", ast::VariableList{}, ty.void_,
                     ast::StatementList{}, ast::FunctionDecorationList{});
 
+  spirv::Builder& b = Build();
+
   ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
 
   EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error();
@@ -1036,6 +1087,8 @@
   auto* func = Func("a_func", ast::VariableList{}, ty.void_,
                     ast::StatementList{}, ast::FunctionDecorationList{});
 
+  spirv::Builder& b = Build();
+
   ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
 
   EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error();
@@ -1063,6 +1116,8 @@
   auto* func = Func("a_func", ast::VariableList{}, ty.void_,
                     ast::StatementList{}, ast::FunctionDecorationList{});
 
+  spirv::Builder& b = Build();
+
   ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
 
   EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error();
@@ -1098,6 +1153,8 @@
   auto* func = Func("a_func", ast::VariableList{}, ty.void_,
                     ast::StatementList{}, ast::FunctionDecorationList{});
 
+  spirv::Builder& b = Build();
+
   ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
 
   EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error();
@@ -1127,6 +1184,8 @@
   auto* func = Func("a_func", ast::VariableList{}, ty.void_,
                     ast::StatementList{}, ast::FunctionDecorationList{});
 
+  spirv::Builder& b = Build();
+
   ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
 
   EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error();
@@ -1161,6 +1220,8 @@
   auto* func = Func("a_func", ast::VariableList{}, ty.void_,
                     ast::StatementList{}, ast::FunctionDecorationList{});
 
+  spirv::Builder& b = Build();
+
   ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
 
   EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error();
@@ -1190,6 +1251,8 @@
   auto* func = Func("a_func", ast::VariableList{}, ty.void_,
                     ast::StatementList{}, ast::FunctionDecorationList{});
 
+  spirv::Builder& b = Build();
+
   ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
 
   EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error();
@@ -1222,6 +1285,8 @@
   auto* func = Func("a_func", ast::VariableList{}, ty.void_,
                     ast::StatementList{}, ast::FunctionDecorationList{});
 
+  spirv::Builder& b = Build();
+
   ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
 
   ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
@@ -1260,6 +1325,8 @@
   auto* func = Func("a_func", ast::VariableList{}, ty.void_,
                     ast::StatementList{}, ast::FunctionDecorationList{});
 
+  spirv::Builder& b = Build();
+
   ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
   ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
   EXPECT_EQ(b.GenerateExpression(expr), 11u) << b.error();
@@ -1295,6 +1362,8 @@
   auto* func = Func("a_func", ast::VariableList{}, ty.void_,
                     ast::StatementList{}, ast::FunctionDecorationList{});
 
+  spirv::Builder& b = Build();
+
   ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
   ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
   EXPECT_EQ(b.GenerateExpression(expr), 11u) << b.error();
diff --git a/src/writer/spirv/builder_intrinsic_texture_test.cc b/src/writer/spirv/builder_intrinsic_texture_test.cc
index 33f2259..f6bbad2 100644
--- a/src/writer/spirv/builder_intrinsic_texture_test.cc
+++ b/src/writer/spirv/builder_intrinsic_texture_test.cc
@@ -28,6 +28,7 @@
 #include "src/writer/spirv/binary_writer.h"
 #include "src/writer/spirv/builder.h"
 #include "src/writer/spirv/spv_dump.h"
+#include "src/writer/spirv/test_helper.h"
 
 namespace tint {
 namespace writer {
@@ -4110,17 +4111,8 @@
           "<unmatched texture overload>"};
 }  // NOLINT - Ignore the length of this function
 
-class IntrinsicTextureTest
-    : public ast::BuilderWithModule,
-      public testing::TestWithParam<ast::intrinsic::test::TextureOverloadCase> {
- protected:
-  void OnVariableBuilt(ast::Variable* var) override {
-    td.RegisterVariableForTesting(var);
-  }
-
-  TypeDeterminer td{mod};
-  spirv::Builder b{mod};
-};
+using IntrinsicTextureTest =
+    TestParamHelper<ast::intrinsic::test::TextureOverloadCase>;
 
 INSTANTIATE_TEST_SUITE_P(
     IntrinsicTextureTest,
@@ -4130,8 +4122,6 @@
 TEST_P(IntrinsicTextureTest, Call) {
   auto param = GetParam();
 
-  b.push_function(Function{});
-
   auto* texture = param.buildTextureVariable(this);
   auto* sampler = param.buildSamplerVariable(this);
 
@@ -4141,6 +4131,9 @@
   EXPECT_TRUE(td.Determine()) << td.error();
   EXPECT_TRUE(td.DetermineResultType(call)) << td.error();
 
+  spirv::Builder& b = Build();
+
+  b.push_function(Function{});
   ASSERT_TRUE(b.GenerateGlobalVariable(texture)) << b.error();
   ASSERT_TRUE(b.GenerateGlobalVariable(sampler)) << b.error();
 
@@ -4176,6 +4169,8 @@
 
   ASSERT_TRUE(td.Determine()) << td.error();
 
+  spirv::Builder& b = Build();
+
   ASSERT_TRUE(b.Build()) << td.error();
 
   BinaryWriter writer;
@@ -4221,13 +4216,15 @@
   auto* texture = param.buildTextureVariable(this);
   auto* sampler = param.buildSamplerVariable(this);
 
-  ASSERT_TRUE(b.GenerateGlobalVariable(texture)) << b.error();
-  ASSERT_TRUE(b.GenerateGlobalVariable(sampler)) << b.error();
-
   auto* call =
       create<ast::CallExpression>(Expr(param.function), param.args(this));
 
   EXPECT_TRUE(td.DetermineResultType(call)) << td.error();
+
+  spirv::Builder& b = Build();
+
+  ASSERT_TRUE(b.GenerateGlobalVariable(texture)) << b.error();
+  ASSERT_TRUE(b.GenerateGlobalVariable(sampler)) << b.error();
   EXPECT_EQ(b.GenerateExpression(call), 0u);
   EXPECT_THAT(b.error(),
               ::testing::StartsWith(
diff --git a/src/writer/spirv/builder_literal_test.cc b/src/writer/spirv/builder_literal_test.cc
index 59d0757..6265094 100644
--- a/src/writer/spirv/builder_literal_test.cc
+++ b/src/writer/spirv/builder_literal_test.cc
@@ -36,6 +36,8 @@
 TEST_F(BuilderTest, Literal_Bool_True) {
   auto* b_true = create<ast::BoolLiteral>(ty.bool_, true);
 
+  spirv::Builder& b = Build();
+
   auto id = b.GenerateLiteralIfNeeded(nullptr, b_true);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(2u, id);
@@ -48,6 +50,8 @@
 TEST_F(BuilderTest, Literal_Bool_False) {
   auto* b_false = create<ast::BoolLiteral>(ty.bool_, false);
 
+  spirv::Builder& b = Build();
+
   auto id = b.GenerateLiteralIfNeeded(nullptr, b_false);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(2u, id);
@@ -61,6 +65,8 @@
   auto* b_true = create<ast::BoolLiteral>(ty.bool_, true);
   auto* b_false = create<ast::BoolLiteral>(ty.bool_, false);
 
+  spirv::Builder& b = Build();
+
   ASSERT_NE(b.GenerateLiteralIfNeeded(nullptr, b_true), 0u);
   ASSERT_FALSE(b.has_error()) << b.error();
   ASSERT_NE(b.GenerateLiteralIfNeeded(nullptr, b_false), 0u);
@@ -77,6 +83,8 @@
 TEST_F(BuilderTest, Literal_I32) {
   auto* i = create<ast::SintLiteral>(ty.i32, -23);
 
+  spirv::Builder& b = Build();
+
   auto id = b.GenerateLiteralIfNeeded(nullptr, i);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(2u, id);
@@ -90,6 +98,8 @@
   auto* i1 = create<ast::SintLiteral>(ty.i32, -23);
   auto* i2 = create<ast::SintLiteral>(ty.i32, -23);
 
+  spirv::Builder& b = Build();
+
   ASSERT_NE(b.GenerateLiteralIfNeeded(nullptr, i1), 0u);
   ASSERT_NE(b.GenerateLiteralIfNeeded(nullptr, i2), 0u);
   ASSERT_FALSE(b.has_error()) << b.error();
@@ -102,6 +112,8 @@
 TEST_F(BuilderTest, Literal_U32) {
   auto* i = create<ast::UintLiteral>(ty.u32, 23);
 
+  spirv::Builder& b = Build();
+
   auto id = b.GenerateLiteralIfNeeded(nullptr, i);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(2u, id);
@@ -115,6 +127,8 @@
   auto* i1 = create<ast::UintLiteral>(ty.u32, 23);
   auto* i2 = create<ast::UintLiteral>(ty.u32, 23);
 
+  spirv::Builder& b = Build();
+
   ASSERT_NE(b.GenerateLiteralIfNeeded(nullptr, i1), 0u);
   ASSERT_NE(b.GenerateLiteralIfNeeded(nullptr, i2), 0u);
   ASSERT_FALSE(b.has_error()) << b.error();
@@ -127,6 +141,8 @@
 TEST_F(BuilderTest, Literal_F32) {
   auto* i = create<ast::FloatLiteral>(ty.f32, 23.245f);
 
+  spirv::Builder& b = Build();
+
   auto id = b.GenerateLiteralIfNeeded(nullptr, i);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(2u, id);
@@ -140,6 +156,8 @@
   auto* i1 = create<ast::FloatLiteral>(ty.f32, 23.245f);
   auto* i2 = create<ast::FloatLiteral>(ty.f32, 23.245f);
 
+  spirv::Builder& b = Build();
+
   ASSERT_NE(b.GenerateLiteralIfNeeded(nullptr, i1), 0u);
   ASSERT_NE(b.GenerateLiteralIfNeeded(nullptr, i2), 0u);
   ASSERT_FALSE(b.has_error()) << b.error();
diff --git a/src/writer/spirv/builder_loop_test.cc b/src/writer/spirv/builder_loop_test.cc
index fc1141a..999600d 100644
--- a/src/writer/spirv/builder_loop_test.cc
+++ b/src/writer/spirv/builder_loop_test.cc
@@ -44,6 +44,9 @@
       create<ast::BlockStatement>(ast::StatementList{}));
 
   ASSERT_TRUE(td.DetermineResultType(loop)) << td.error();
+
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
 
   EXPECT_TRUE(b.GenerateLoopStatement(loop)) << b.error();
@@ -75,6 +78,8 @@
   td.RegisterVariableForTesting(var);
   ASSERT_TRUE(td.DetermineResultType(loop)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
 
@@ -118,6 +123,8 @@
   td.RegisterVariableForTesting(var);
   ASSERT_TRUE(td.DetermineResultType(loop)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
 
@@ -156,6 +163,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(loop)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
 
   EXPECT_TRUE(b.GenerateLoopStatement(loop)) << b.error();
@@ -184,6 +193,8 @@
 
   ASSERT_TRUE(td.DetermineResultType(loop)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
 
   EXPECT_TRUE(b.GenerateLoopStatement(loop)) << b.error();
diff --git a/src/writer/spirv/builder_return_test.cc b/src/writer/spirv/builder_return_test.cc
index 017ac29..94ece56 100644
--- a/src/writer/spirv/builder_return_test.cc
+++ b/src/writer/spirv/builder_return_test.cc
@@ -37,6 +37,8 @@
 TEST_F(BuilderTest, Return) {
   auto* ret = create<ast::ReturnStatement>();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_TRUE(b.GenerateReturnStatement(ret));
   ASSERT_FALSE(b.has_error()) << b.error();
@@ -52,6 +54,8 @@
 
   EXPECT_TRUE(td.DetermineResultType(ret)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_TRUE(b.GenerateReturnStatement(ret));
   ASSERT_FALSE(b.has_error()) << b.error();
@@ -75,6 +79,8 @@
   td.RegisterVariableForTesting(var);
   EXPECT_TRUE(td.DetermineResultType(ret)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
   EXPECT_TRUE(b.GenerateReturnStatement(ret)) << b.error();
diff --git a/src/writer/spirv/builder_switch_test.cc b/src/writer/spirv/builder_switch_test.cc
index d320474..57e74dd 100644
--- a/src/writer/spirv/builder_switch_test.cc
+++ b/src/writer/spirv/builder_switch_test.cc
@@ -46,6 +46,8 @@
   auto* expr = create<ast::SwitchStatement>(Expr(1), ast::CaseStatementList{});
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
 
   EXPECT_TRUE(b.GenerateSwitchStatement(expr)) << b.error();
@@ -97,6 +99,8 @@
   auto* func = Func("a_func", {}, ty.i32, ast::StatementList{},
                     ast::FunctionDecorationList{});
 
+  spirv::Builder& b = Build();
+
   ASSERT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
   ASSERT_TRUE(b.GenerateGlobalVariable(a)) << b.error();
   ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
@@ -158,6 +162,8 @@
   auto* func = Func("a_func", {}, ty.i32, ast::StatementList{},
                     ast::FunctionDecorationList{});
 
+  spirv::Builder& b = Build();
+
   ASSERT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
   ASSERT_TRUE(b.GenerateGlobalVariable(a)) << b.error();
   ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
@@ -232,6 +238,8 @@
   auto* func = Func("a_func", {}, ty.i32, ast::StatementList{},
                     ast::FunctionDecorationList{});
 
+  spirv::Builder& b = Build();
+
   ASSERT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
   ASSERT_TRUE(b.GenerateGlobalVariable(a)) << b.error();
   ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
@@ -315,6 +323,8 @@
   auto* func = Func("a_func", {}, ty.i32, ast::StatementList{},
                     ast::FunctionDecorationList{});
 
+  spirv::Builder& b = Build();
+
   ASSERT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
   ASSERT_TRUE(b.GenerateGlobalVariable(a)) << b.error();
   ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
@@ -382,6 +392,8 @@
   auto* func = Func("a_func", {}, ty.i32, ast::StatementList{},
                     ast::FunctionDecorationList{});
 
+  spirv::Builder& b = Build();
+
   ASSERT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
   ASSERT_TRUE(b.GenerateGlobalVariable(a)) << b.error();
   ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
@@ -425,6 +437,8 @@
   auto* func = Func("a_func", {}, ty.i32, ast::StatementList{},
                     ast::FunctionDecorationList{});
 
+  spirv::Builder& b = Build();
+
   ASSERT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
   ASSERT_TRUE(b.GenerateGlobalVariable(a)) << b.error();
   ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
diff --git a/src/writer/spirv/builder_test.cc b/src/writer/spirv/builder_test.cc
index fb2549f..9cedea7 100644
--- a/src/writer/spirv/builder_test.cc
+++ b/src/writer/spirv/builder_test.cc
@@ -31,6 +31,8 @@
 using BuilderTest = TestHelper;
 
 TEST_F(BuilderTest, InsertsPreamble) {
+  spirv::Builder& b = Build();
+
   ASSERT_TRUE(b.Build());
   EXPECT_EQ(DumpBuilder(b), R"(OpCapability Shader
 OpMemoryModel Logical GLSL450
@@ -38,6 +40,8 @@
 }
 
 TEST_F(BuilderTest, TracksIdBounds) {
+  spirv::Builder& b = Build();
+
   for (size_t i = 0; i < 5; i++) {
     EXPECT_EQ(b.next_id(), i + 1);
   }
@@ -46,6 +50,8 @@
 }
 
 TEST_F(BuilderTest, Capabilities_Dedup) {
+  spirv::Builder& b = Build();
+
   b.push_capability(SpvCapabilityShader);
   b.push_capability(SpvCapabilityShader);
   b.push_capability(SpvCapabilityShader);
diff --git a/src/writer/spirv/builder_type_test.cc b/src/writer/spirv/builder_type_test.cc
index 756e885..0a00317 100644
--- a/src/writer/spirv/builder_type_test.cc
+++ b/src/writer/spirv/builder_type_test.cc
@@ -53,6 +53,9 @@
 
 TEST_F(BuilderTest_Type, GenerateAlias) {
   auto* alias_type = ty.alias("my_type", ty.f32);
+
+  spirv::Builder& b = Build();
+
   auto id = b.GenerateTypeIfNeeded(alias_type);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(id, 1u);
@@ -65,6 +68,8 @@
 TEST_F(BuilderTest_Type, ReturnsGeneratedAlias) {
   auto* alias_type = ty.alias("my_type", ty.f32);
 
+  spirv::Builder& b = Build();
+
   EXPECT_EQ(b.GenerateTypeIfNeeded(alias_type), 1u);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(b.GenerateTypeIfNeeded(ty.i32), 2u);
@@ -77,6 +82,9 @@
 
 TEST_F(BuilderTest_Type, GenerateRuntimeArray) {
   type::Array ary(ty.i32, 0, ast::ArrayDecorationList{});
+
+  spirv::Builder& b = Build();
+
   auto id = b.GenerateTypeIfNeeded(&ary);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(1u, id);
@@ -89,6 +97,8 @@
 TEST_F(BuilderTest_Type, ReturnsGeneratedRuntimeArray) {
   type::Array ary(ty.i32, 0, ast::ArrayDecorationList{});
 
+  spirv::Builder& b = Build();
+
   EXPECT_EQ(b.GenerateTypeIfNeeded(&ary), 1u);
   EXPECT_EQ(b.GenerateTypeIfNeeded(&ary), 1u);
   ASSERT_FALSE(b.has_error()) << b.error();
@@ -100,6 +110,9 @@
 
 TEST_F(BuilderTest_Type, GenerateArray) {
   type::Array ary(ty.i32, 4, ast::ArrayDecorationList{});
+
+  spirv::Builder& b = Build();
+
   auto id = b.GenerateTypeIfNeeded(&ary);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(1u, id);
@@ -117,6 +130,8 @@
                       create<ast::StrideDecoration>(16u),
                   });
 
+  spirv::Builder& b = Build();
+
   auto id = b.GenerateTypeIfNeeded(&ary);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(1u, id);
@@ -134,6 +149,8 @@
 TEST_F(BuilderTest_Type, ReturnsGeneratedArray) {
   type::Array ary(ty.i32, 4, ast::ArrayDecorationList{});
 
+  spirv::Builder& b = Build();
+
   EXPECT_EQ(b.GenerateTypeIfNeeded(&ary), 1u);
   EXPECT_EQ(b.GenerateTypeIfNeeded(&ary), 1u);
   ASSERT_FALSE(b.has_error()) << b.error();
@@ -146,6 +163,8 @@
 }
 
 TEST_F(BuilderTest_Type, GenerateBool) {
+  spirv::Builder& b = Build();
+
   auto id = b.GenerateTypeIfNeeded(ty.bool_);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(id, 1u);
@@ -156,6 +175,8 @@
 }
 
 TEST_F(BuilderTest_Type, ReturnsGeneratedBool) {
+  spirv::Builder& b = Build();
+
   EXPECT_EQ(b.GenerateTypeIfNeeded(ty.bool_), 1u);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(b.GenerateTypeIfNeeded(ty.i32), 2u);
@@ -165,6 +186,8 @@
 }
 
 TEST_F(BuilderTest_Type, GenerateF32) {
+  spirv::Builder& b = Build();
+
   auto id = b.GenerateTypeIfNeeded(ty.f32);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(id, 1u);
@@ -175,6 +198,8 @@
 }
 
 TEST_F(BuilderTest_Type, ReturnsGeneratedF32) {
+  spirv::Builder& b = Build();
+
   EXPECT_EQ(b.GenerateTypeIfNeeded(ty.f32), 1u);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(b.GenerateTypeIfNeeded(ty.i32), 2u);
@@ -184,6 +209,8 @@
 }
 
 TEST_F(BuilderTest_Type, GenerateI32) {
+  spirv::Builder& b = Build();
+
   auto id = b.GenerateTypeIfNeeded(ty.i32);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(id, 1u);
@@ -194,6 +221,8 @@
 }
 
 TEST_F(BuilderTest_Type, ReturnsGeneratedI32) {
+  spirv::Builder& b = Build();
+
   EXPECT_EQ(b.GenerateTypeIfNeeded(ty.i32), 1u);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(b.GenerateTypeIfNeeded(ty.f32), 2u);
@@ -203,6 +232,8 @@
 }
 
 TEST_F(BuilderTest_Type, GenerateMatrix) {
+  spirv::Builder& b = Build();
+
   auto id = b.GenerateTypeIfNeeded(ty.mat2x3<f32>());
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(id, 1u);
@@ -216,6 +247,9 @@
 
 TEST_F(BuilderTest_Type, ReturnsGeneratedMatrix) {
   auto* mat = ty.mat4x3<i32>();
+
+  spirv::Builder& b = Build();
+
   EXPECT_EQ(b.GenerateTypeIfNeeded(mat), 1u);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(b.GenerateTypeIfNeeded(ty.i32), 3u);
@@ -226,6 +260,9 @@
 
 TEST_F(BuilderTest_Type, GeneratePtr) {
   type::Pointer ptr(ty.i32, ast::StorageClass::kOutput);
+
+  spirv::Builder& b = Build();
+
   auto id = b.GenerateTypeIfNeeded(&ptr);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(1u, id);
@@ -237,6 +274,9 @@
 
 TEST_F(BuilderTest_Type, ReturnsGeneratedPtr) {
   type::Pointer ptr(ty.i32, ast::StorageClass::kOutput);
+
+  spirv::Builder& b = Build();
+
   EXPECT_EQ(b.GenerateTypeIfNeeded(&ptr), 1u);
   EXPECT_EQ(b.GenerateTypeIfNeeded(&ptr), 1u);
 }
@@ -246,6 +286,8 @@
       create<ast::Struct>(ast::StructMemberList{}, ast::StructDecorationList{});
   auto* s_type = ty.struct_("S", s);
 
+  spirv::Builder& b = Build();
+
   auto id = b.GenerateTypeIfNeeded(s_type);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(id, 1u);
@@ -262,6 +304,8 @@
                                 ast::StructDecorationList{});
   auto* s_type = ty.struct_("my_struct", s);
 
+  spirv::Builder& b = Build();
+
   auto id = b.GenerateTypeIfNeeded(s_type);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(id, 1u);
@@ -282,6 +326,8 @@
                                 struct_decos);
   auto* s_type = ty.struct_("my_struct", s);
 
+  spirv::Builder& b = Build();
+
   auto id = b.GenerateTypeIfNeeded(s_type);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(id, 1u);
@@ -303,6 +349,8 @@
       ast::StructDecorationList{});
   auto* s_type = ty.struct_("S", s);
 
+  spirv::Builder& b = Build();
+
   auto id = b.GenerateTypeIfNeeded(s_type);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(id, 1u);
@@ -327,6 +375,8 @@
                           ast::StructDecorationList{});
   auto* s_type = ty.struct_("S", s);
 
+  spirv::Builder& b = Build();
+
   auto id = b.GenerateTypeIfNeeded(s_type);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(id, 1u);
@@ -357,6 +407,8 @@
       ast::StructDecorationList{});
   auto* s_type = ty.struct_("S", s);
 
+  spirv::Builder& b = Build();
+
   auto id = b.GenerateTypeIfNeeded(s_type);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(id, 1u);
@@ -408,6 +460,8 @@
       ast::StructDecorationList{});
   auto* s_type = ty.struct_("S", s);
 
+  spirv::Builder& b = Build();
+
   auto id = b.GenerateTypeIfNeeded(s_type);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(id, 1u);
@@ -444,6 +498,8 @@
 }
 
 TEST_F(BuilderTest_Type, GenerateU32) {
+  spirv::Builder& b = Build();
+
   auto id = b.GenerateTypeIfNeeded(ty.u32);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(id, 1u);
@@ -454,6 +510,8 @@
 }
 
 TEST_F(BuilderTest_Type, ReturnsGeneratedU32) {
+  spirv::Builder& b = Build();
+
   EXPECT_EQ(b.GenerateTypeIfNeeded(ty.u32), 1u);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(b.GenerateTypeIfNeeded(ty.f32), 2u);
@@ -463,6 +521,8 @@
 }
 
 TEST_F(BuilderTest_Type, GenerateVector) {
+  spirv::Builder& b = Build();
+
   auto id = b.GenerateTypeIfNeeded(ty.vec3<f32>());
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(id, 1u);
@@ -475,6 +535,9 @@
 
 TEST_F(BuilderTest_Type, ReturnsGeneratedVector) {
   auto* vec_type = ty.vec3<i32>();
+
+  spirv::Builder& b = Build();
+
   EXPECT_EQ(b.GenerateTypeIfNeeded(vec_type), 1u);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(b.GenerateTypeIfNeeded(ty.i32), 2u);
@@ -484,6 +547,8 @@
 }
 
 TEST_F(BuilderTest_Type, GenerateVoid) {
+  spirv::Builder& b = Build();
+
   auto id = b.GenerateTypeIfNeeded(ty.void_);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(id, 1u);
@@ -494,6 +559,8 @@
 }
 
 TEST_F(BuilderTest_Type, ReturnsGeneratedVoid) {
+  spirv::Builder& b = Build();
+
   EXPECT_EQ(b.GenerateTypeIfNeeded(ty.void_), 1u);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(b.GenerateTypeIfNeeded(ty.i32), 2u);
@@ -514,6 +581,8 @@
 TEST_P(PtrDataTest, ConvertStorageClass) {
   auto params = GetParam();
 
+  spirv::Builder& b = Build();
+
   EXPECT_EQ(b.ConvertStorageClass(params.ast_class), params.result);
 }
 INSTANTIATE_TEST_SUITE_P(
@@ -535,6 +604,8 @@
 TEST_F(BuilderTest_Type, DepthTexture_Generate_2d) {
   type::DepthTexture two_d(type::TextureDimension::k2d);
 
+  spirv::Builder& b = Build();
+
   auto id_two_d = b.GenerateTypeIfNeeded(&two_d);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(1u, id_two_d);
@@ -547,6 +618,8 @@
 TEST_F(BuilderTest_Type, DepthTexture_Generate_2dArray) {
   type::DepthTexture two_d_array(type::TextureDimension::k2dArray);
 
+  spirv::Builder& b = Build();
+
   auto id_two_d_array = b.GenerateTypeIfNeeded(&two_d_array);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(1u, id_two_d_array);
@@ -559,6 +632,8 @@
 TEST_F(BuilderTest_Type, DepthTexture_Generate_Cube) {
   type::DepthTexture cube(type::TextureDimension::kCube);
 
+  spirv::Builder& b = Build();
+
   auto id_cube = b.GenerateTypeIfNeeded(&cube);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(1u, id_cube);
@@ -572,6 +647,8 @@
 TEST_F(BuilderTest_Type, DepthTexture_Generate_CubeArray) {
   type::DepthTexture cube_array(type::TextureDimension::kCubeArray);
 
+  spirv::Builder& b = Build();
+
   auto id_cube_array = b.GenerateTypeIfNeeded(&cube_array);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(1u, id_cube_array);
@@ -587,6 +664,8 @@
 TEST_F(BuilderTest_Type, MultisampledTexture_Generate_2d_i32) {
   type::MultisampledTexture ms(type::TextureDimension::k2d, ty.i32);
 
+  spirv::Builder& b = Build();
+
   EXPECT_EQ(1u, b.GenerateTypeIfNeeded(&ms));
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 1
@@ -597,6 +676,8 @@
 TEST_F(BuilderTest_Type, MultisampledTexture_Generate_2d_u32) {
   type::MultisampledTexture ms(type::TextureDimension::k2d, ty.u32);
 
+  spirv::Builder& b = Build();
+
   EXPECT_EQ(b.GenerateTypeIfNeeded(&ms), 1u);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(DumpInstructions(b.types()),
@@ -608,6 +689,8 @@
 TEST_F(BuilderTest_Type, MultisampledTexture_Generate_2d_f32) {
   type::MultisampledTexture ms(type::TextureDimension::k2d, ty.f32);
 
+  spirv::Builder& b = Build();
+
   EXPECT_EQ(b.GenerateTypeIfNeeded(&ms), 1u);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(DumpInstructions(b.types()),
@@ -619,6 +702,8 @@
 TEST_F(BuilderTest_Type, SampledTexture_Generate_1d_i32) {
   type::SampledTexture s(type::TextureDimension::k1d, ty.i32);
 
+  spirv::Builder& b = Build();
+
   EXPECT_EQ(b.GenerateTypeIfNeeded(&s), 1u);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(DumpInstructions(b.types()),
@@ -634,6 +719,8 @@
 TEST_F(BuilderTest_Type, SampledTexture_Generate_1d_u32) {
   type::SampledTexture s(type::TextureDimension::k1d, ty.u32);
 
+  spirv::Builder& b = Build();
+
   EXPECT_EQ(b.GenerateTypeIfNeeded(&s), 1u);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(DumpInstructions(b.types()),
@@ -649,6 +736,8 @@
 TEST_F(BuilderTest_Type, SampledTexture_Generate_1d_f32) {
   type::SampledTexture s(type::TextureDimension::k1d, ty.f32);
 
+  spirv::Builder& b = Build();
+
   EXPECT_EQ(b.GenerateTypeIfNeeded(&s), 1u);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(DumpInstructions(b.types()),
@@ -664,6 +753,8 @@
 TEST_F(BuilderTest_Type, SampledTexture_Generate_1dArray) {
   type::SampledTexture s(type::TextureDimension::k1dArray, ty.f32);
 
+  spirv::Builder& b = Build();
+
   EXPECT_EQ(b.GenerateTypeIfNeeded(&s), 1u);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(DumpInstructions(b.types()),
@@ -679,6 +770,8 @@
 TEST_F(BuilderTest_Type, SampledTexture_Generate_2d) {
   type::SampledTexture s(type::TextureDimension::k2d, ty.f32);
 
+  spirv::Builder& b = Build();
+
   EXPECT_EQ(b.GenerateTypeIfNeeded(&s), 1u);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(DumpInstructions(b.types()),
@@ -690,6 +783,8 @@
 TEST_F(BuilderTest_Type, SampledTexture_Generate_2d_array) {
   type::SampledTexture s(type::TextureDimension::k2dArray, ty.f32);
 
+  spirv::Builder& b = Build();
+
   EXPECT_EQ(b.GenerateTypeIfNeeded(&s), 1u);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(DumpInstructions(b.types()),
@@ -701,6 +796,8 @@
 TEST_F(BuilderTest_Type, SampledTexture_Generate_3d) {
   type::SampledTexture s(type::TextureDimension::k3d, ty.f32);
 
+  spirv::Builder& b = Build();
+
   EXPECT_EQ(b.GenerateTypeIfNeeded(&s), 1u);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(DumpInstructions(b.types()),
@@ -712,6 +809,8 @@
 TEST_F(BuilderTest_Type, SampledTexture_Generate_Cube) {
   type::SampledTexture s(type::TextureDimension::kCube, ty.f32);
 
+  spirv::Builder& b = Build();
+
   EXPECT_EQ(b.GenerateTypeIfNeeded(&s), 1u);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(DumpInstructions(b.types()),
@@ -724,6 +823,8 @@
 TEST_F(BuilderTest_Type, SampledTexture_Generate_CubeArray) {
   type::SampledTexture s(type::TextureDimension::kCubeArray, ty.f32);
 
+  spirv::Builder& b = Build();
+
   EXPECT_EQ(b.GenerateTypeIfNeeded(&s), 1u);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(DumpInstructions(b.types()),
@@ -740,6 +841,9 @@
                          type::ImageFormat::kR16Float);
 
   ASSERT_TRUE(td.DetermineStorageTextureSubtype(&s)) << td.error();
+
+  spirv::Builder& b = Build();
+
   EXPECT_EQ(b.GenerateTypeIfNeeded(&s), 1u);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
@@ -757,6 +861,9 @@
                          type::ImageFormat::kR8Snorm);
 
   ASSERT_TRUE(td.DetermineStorageTextureSubtype(&s)) << td.error();
+
+  spirv::Builder& b = Build();
+
   EXPECT_EQ(b.GenerateTypeIfNeeded(&s), 1u);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
@@ -774,6 +881,9 @@
                          type::ImageFormat::kR8Unorm);
 
   ASSERT_TRUE(td.DetermineStorageTextureSubtype(&s)) << td.error();
+
+  spirv::Builder& b = Build();
+
   EXPECT_EQ(b.GenerateTypeIfNeeded(&s), 1u);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
@@ -791,6 +901,9 @@
                          type::ImageFormat::kR8Uint);
 
   ASSERT_TRUE(td.DetermineStorageTextureSubtype(&s)) << td.error();
+
+  spirv::Builder& b = Build();
+
   EXPECT_EQ(b.GenerateTypeIfNeeded(&s), 1u);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 0
@@ -803,6 +916,9 @@
                          type::ImageFormat::kR8Sint);
 
   ASSERT_TRUE(td.DetermineStorageTextureSubtype(&s)) << td.error();
+
+  spirv::Builder& b = Build();
+
   EXPECT_EQ(b.GenerateTypeIfNeeded(&s), 1u);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 1
@@ -815,6 +931,9 @@
                          type::ImageFormat::kR16Float);
 
   ASSERT_TRUE(td.DetermineStorageTextureSubtype(&s)) << td.error();
+
+  spirv::Builder& b = Build();
+
   EXPECT_EQ(b.GenerateTypeIfNeeded(&s), 1u);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
@@ -832,6 +951,9 @@
                          type::ImageFormat::kR16Float);
 
   ASSERT_TRUE(td.DetermineStorageTextureSubtype(&s)) << td.error();
+
+  spirv::Builder& b = Build();
+
   EXPECT_EQ(b.GenerateTypeIfNeeded(&s), 1u);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
@@ -844,6 +966,9 @@
                          type::ImageFormat::kR16Float);
 
   ASSERT_TRUE(td.DetermineStorageTextureSubtype(&s)) << td.error();
+
+  spirv::Builder& b = Build();
+
   EXPECT_EQ(b.GenerateTypeIfNeeded(&s), 1u);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
@@ -856,6 +981,9 @@
                          type::ImageFormat::kR16Float);
 
   ASSERT_TRUE(td.DetermineStorageTextureSubtype(&s)) << td.error();
+
+  spirv::Builder& b = Build();
+
   EXPECT_EQ(b.GenerateTypeIfNeeded(&s), 1u);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
@@ -869,6 +997,9 @@
                          type::ImageFormat::kR32Float);
 
   ASSERT_TRUE(td.DetermineStorageTextureSubtype(&s)) << td.error();
+
+  spirv::Builder& b = Build();
+
   EXPECT_EQ(b.GenerateTypeIfNeeded(&s), 1u);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
@@ -882,6 +1013,9 @@
                          type::ImageFormat::kR32Sint);
 
   ASSERT_TRUE(td.DetermineStorageTextureSubtype(&s)) << td.error();
+
+  spirv::Builder& b = Build();
+
   EXPECT_EQ(b.GenerateTypeIfNeeded(&s), 1u);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 1
@@ -895,6 +1029,9 @@
                          type::ImageFormat::kR32Uint);
 
   ASSERT_TRUE(td.DetermineStorageTextureSubtype(&s)) << td.error();
+
+  spirv::Builder& b = Build();
+
   EXPECT_EQ(b.GenerateTypeIfNeeded(&s), 1u);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 0
@@ -904,6 +1041,9 @@
 
 TEST_F(BuilderTest_Type, Sampler) {
   type::Sampler sampler(type::SamplerKind::kSampler);
+
+  spirv::Builder& b = Build();
+
   EXPECT_EQ(b.GenerateTypeIfNeeded(&sampler), 1u);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(DumpInstructions(b.types()), "%1 = OpTypeSampler\n");
@@ -911,6 +1051,9 @@
 
 TEST_F(BuilderTest_Type, ComparisonSampler) {
   type::Sampler sampler(type::SamplerKind::kComparisonSampler);
+
+  spirv::Builder& b = Build();
+
   EXPECT_EQ(b.GenerateTypeIfNeeded(&sampler), 1u);
   ASSERT_FALSE(b.has_error()) << b.error();
   EXPECT_EQ(DumpInstructions(b.types()), "%1 = OpTypeSampler\n");
@@ -918,9 +1061,12 @@
 
 TEST_F(BuilderTest_Type, Dedup_Sampler_And_ComparisonSampler) {
   type::Sampler comp_sampler(type::SamplerKind::kComparisonSampler);
+  type::Sampler sampler(type::SamplerKind::kSampler);
+
+  spirv::Builder& b = Build();
+
   EXPECT_EQ(b.GenerateTypeIfNeeded(&comp_sampler), 1u);
 
-  type::Sampler sampler(type::SamplerKind::kSampler);
   EXPECT_EQ(b.GenerateTypeIfNeeded(&sampler), 1u);
 
   ASSERT_FALSE(b.has_error()) << b.error();
diff --git a/src/writer/spirv/builder_unary_op_expression_test.cc b/src/writer/spirv/builder_unary_op_expression_test.cc
index 409994c..c47723b 100644
--- a/src/writer/spirv/builder_unary_op_expression_test.cc
+++ b/src/writer/spirv/builder_unary_op_expression_test.cc
@@ -20,11 +20,11 @@
 #include "src/ast/identifier_expression.h"
 #include "src/ast/scalar_constructor_expression.h"
 #include "src/ast/sint_literal.h"
+#include "src/ast/unary_op_expression.h"
 #include "src/type/bool_type.h"
 #include "src/type/f32_type.h"
 #include "src/type/i32_type.h"
 #include "src/type/vector_type.h"
-#include "src/ast/unary_op_expression.h"
 #include "src/type_determiner.h"
 #include "src/writer/spirv/builder.h"
 #include "src/writer/spirv/spv_dump.h"
@@ -41,6 +41,8 @@
   auto* expr = create<ast::UnaryOpExpression>(ast::UnaryOp::kNegation, Expr(1));
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_EQ(b.GenerateUnaryOpExpression(expr), 1u) << b.error();
   EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 1
@@ -56,6 +58,8 @@
       create<ast::UnaryOpExpression>(ast::UnaryOp::kNegation, Expr(1.f));
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_EQ(b.GenerateUnaryOpExpression(expr), 1u) << b.error();
   EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
@@ -70,6 +74,8 @@
   auto* expr = create<ast::UnaryOpExpression>(ast::UnaryOp::kNot, Expr(false));
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_EQ(b.GenerateUnaryOpExpression(expr), 1u) << b.error();
   EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeBool
@@ -89,6 +95,8 @@
   td.RegisterVariableForTesting(var);
   EXPECT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  spirv::Builder& b = Build();
+
   b.push_function(Function{});
   EXPECT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
   EXPECT_EQ(b.GenerateUnaryOpExpression(expr), 6u) << b.error();
diff --git a/src/writer/spirv/test_helper.h b/src/writer/spirv/test_helper.h
index cbc3d0e..6ee8b64 100644
--- a/src/writer/spirv/test_helper.h
+++ b/src/writer/spirv/test_helper.h
@@ -32,13 +32,23 @@
 template <typename BASE>
 class TestHelperBase : public ast::BuilderWithModule, public BASE {
  public:
-  TestHelperBase() : td(mod), b(mod) {}
+  TestHelperBase() : td(mod) {}
   ~TestHelperBase() override = default;
 
+  /// Builds and returns a spirv::Builder from the module.
+  /// @note The spirv::Builder is only built once. Multiple calls to Build()
+  /// will return the same spirv::Builder without rebuilding.
+  /// @return the built spirv::Builder
+  spirv::Builder& Build() {
+    if (spirv_builder) {
+      return *spirv_builder;
+    }
+    spirv_builder = std::make_unique<spirv::Builder>(mod);
+    return *spirv_builder;
+  }
+
   /// The type determiner
   TypeDeterminer td;
-  /// The generator
-  spirv::Builder b;
 
  protected:
   /// Called whenever a new variable is built with `Var()`.
@@ -46,6 +56,9 @@
   void OnVariableBuilt(ast::Variable* var) override {
     td.RegisterVariableForTesting(var);
   }
+
+ private:
+  std::unique_ptr<spirv::Builder> spirv_builder;
 };
 using TestHelper = TestHelperBase<testing::Test>;
 
diff --git a/src/writer/wgsl/generator_impl_alias_type_test.cc b/src/writer/wgsl/generator_impl_alias_type_test.cc
index fc158a1..77ca153 100644
--- a/src/writer/wgsl/generator_impl_alias_type_test.cc
+++ b/src/writer/wgsl/generator_impl_alias_type_test.cc
@@ -29,6 +29,8 @@
 
 TEST_F(WgslGeneratorImplTest, EmitAlias_F32) {
   auto* alias = ty.alias("a", ty.f32);
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitConstructedType(alias)) << gen.error();
   EXPECT_EQ(gen.result(), R"(type a = f32;
 )");
@@ -43,6 +45,8 @@
   auto* s = ty.struct_("A", str);
   auto* alias = ty.alias("B", s);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitConstructedType(s)) << gen.error();
   ASSERT_TRUE(gen.EmitConstructedType(alias)) << gen.error();
   EXPECT_EQ(gen.result(), R"(struct A {
@@ -63,6 +67,8 @@
   auto* s = ty.struct_("A", str);
   auto* alias = ty.alias("B", s);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitConstructedType(alias)) << gen.error();
   EXPECT_EQ(gen.result(), R"(type B = A;
 )");
diff --git a/src/writer/wgsl/generator_impl_array_accessor_test.cc b/src/writer/wgsl/generator_impl_array_accessor_test.cc
index 6a3e208..1aab325 100644
--- a/src/writer/wgsl/generator_impl_array_accessor_test.cc
+++ b/src/writer/wgsl/generator_impl_array_accessor_test.cc
@@ -36,6 +36,8 @@
 
   auto* expr = create<ast::ArrayAccessorExpression>(ary, idx);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitExpression(expr)) << gen.error();
   EXPECT_EQ(gen.result(), "ary[5]");
 }
@@ -46,6 +48,8 @@
 
   auto* expr = create<ast::ArrayAccessorExpression>(ary, idx);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitArrayAccessor(expr)) << gen.error();
   EXPECT_EQ(gen.result(), "ary[idx]");
 }
diff --git a/src/writer/wgsl/generator_impl_assign_test.cc b/src/writer/wgsl/generator_impl_assign_test.cc
index fc720a0..524324e 100644
--- a/src/writer/wgsl/generator_impl_assign_test.cc
+++ b/src/writer/wgsl/generator_impl_assign_test.cc
@@ -33,6 +33,8 @@
   auto* rhs = Expr("rhs");
   auto* assign = create<ast::AssignmentStatement>(lhs, rhs);
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(assign)) << gen.error();
diff --git a/src/writer/wgsl/generator_impl_binary_test.cc b/src/writer/wgsl/generator_impl_binary_test.cc
index 70f3fa7..e955f30 100644
--- a/src/writer/wgsl/generator_impl_binary_test.cc
+++ b/src/writer/wgsl/generator_impl_binary_test.cc
@@ -42,6 +42,8 @@
 
   auto* expr = create<ast::BinaryExpression>(params.op, left, right);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitExpression(expr)) << gen.error();
   EXPECT_EQ(gen.result(), params.result);
 }
diff --git a/src/writer/wgsl/generator_impl_bitcast_test.cc b/src/writer/wgsl/generator_impl_bitcast_test.cc
index 7441780..3a67df4 100644
--- a/src/writer/wgsl/generator_impl_bitcast_test.cc
+++ b/src/writer/wgsl/generator_impl_bitcast_test.cc
@@ -32,6 +32,8 @@
   auto* id = Expr("id");
   auto* bitcast = create<ast::BitcastExpression>(ty.f32, id);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitExpression(bitcast)) << gen.error();
   EXPECT_EQ(gen.result(), "bitcast<f32>(id)");
 }
diff --git a/src/writer/wgsl/generator_impl_block_test.cc b/src/writer/wgsl/generator_impl_block_test.cc
index ef843d4..027136c 100644
--- a/src/writer/wgsl/generator_impl_block_test.cc
+++ b/src/writer/wgsl/generator_impl_block_test.cc
@@ -31,6 +31,9 @@
   auto* b = create<ast::BlockStatement>(ast::StatementList{
       create<ast::DiscardStatement>(),
   });
+
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(b)) << gen.error();
@@ -44,6 +47,8 @@
   auto* b = create<ast::BlockStatement>(ast::StatementList{
       create<ast::DiscardStatement>(),
   });
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitBlock(b)) << gen.error();
diff --git a/src/writer/wgsl/generator_impl_break_test.cc b/src/writer/wgsl/generator_impl_break_test.cc
index bb0385a..375bfef 100644
--- a/src/writer/wgsl/generator_impl_break_test.cc
+++ b/src/writer/wgsl/generator_impl_break_test.cc
@@ -30,6 +30,8 @@
 TEST_F(WgslGeneratorImplTest, Emit_Break) {
   auto* b = create<ast::BreakStatement>();
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(b)) << gen.error();
diff --git a/src/writer/wgsl/generator_impl_call_test.cc b/src/writer/wgsl/generator_impl_call_test.cc
index f51e3da..1bf5db1 100644
--- a/src/writer/wgsl/generator_impl_call_test.cc
+++ b/src/writer/wgsl/generator_impl_call_test.cc
@@ -32,6 +32,8 @@
   auto* id = Expr("my_func");
   auto* call = create<ast::CallExpression>(id, ast::ExpressionList{});
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitExpression(call)) << gen.error();
   EXPECT_EQ(gen.result(), "my_func()");
 }
@@ -41,6 +43,8 @@
   auto* call = create<ast::CallExpression>(
       id, ast::ExpressionList{Expr("param1"), Expr("param2")});
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitExpression(call)) << gen.error();
   EXPECT_EQ(gen.result(), "my_func(param1, param2)");
 }
@@ -51,6 +55,8 @@
   auto* call = create<ast::CallStatement>(create<ast::CallExpression>(
       id, ast::ExpressionList{Expr("param1"), Expr("param2")}));
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
   ASSERT_TRUE(gen.EmitStatement(call)) << gen.error();
   EXPECT_EQ(gen.result(), "  my_func(param1, param2);\n");
diff --git a/src/writer/wgsl/generator_impl_case_test.cc b/src/writer/wgsl/generator_impl_case_test.cc
index cd52219..736ca39 100644
--- a/src/writer/wgsl/generator_impl_case_test.cc
+++ b/src/writer/wgsl/generator_impl_case_test.cc
@@ -38,6 +38,8 @@
   lit.push_back(create<ast::SintLiteral>(ty.i32, 5));
   auto* c = create<ast::CaseStatement>(lit, body);
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitCase(c)) << gen.error();
@@ -56,6 +58,8 @@
   lit.push_back(create<ast::SintLiteral>(ty.i32, 6));
   auto* c = create<ast::CaseStatement>(lit, body);
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitCase(c)) << gen.error();
@@ -71,6 +75,8 @@
   });
   auto* c = create<ast::CaseStatement>(ast::CaseSelectorList{}, body);
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitCase(c)) << gen.error();
diff --git a/src/writer/wgsl/generator_impl_cast_test.cc b/src/writer/wgsl/generator_impl_cast_test.cc
index ff2881b..b40e015 100644
--- a/src/writer/wgsl/generator_impl_cast_test.cc
+++ b/src/writer/wgsl/generator_impl_cast_test.cc
@@ -31,6 +31,8 @@
 TEST_F(WgslGeneratorImplTest, EmitExpression_Cast) {
   auto* cast = Construct<f32>("id");
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitExpression(cast)) << gen.error();
   EXPECT_EQ(gen.result(), "f32(id)");
 }
diff --git a/src/writer/wgsl/generator_impl_constructor_test.cc b/src/writer/wgsl/generator_impl_constructor_test.cc
index 4705802..b675712 100644
--- a/src/writer/wgsl/generator_impl_constructor_test.cc
+++ b/src/writer/wgsl/generator_impl_constructor_test.cc
@@ -36,68 +36,106 @@
 using WgslGeneratorImplTest = TestHelper;
 
 TEST_F(WgslGeneratorImplTest, EmitConstructor_Bool) {
-  ASSERT_TRUE(gen.EmitConstructor(Expr(false))) << gen.error();
+  auto* expr = Expr(false);
+
+  GeneratorImpl& gen = Build();
+
+  ASSERT_TRUE(gen.EmitConstructor(expr)) << gen.error();
   EXPECT_EQ(gen.result(), "false");
 }
 
 TEST_F(WgslGeneratorImplTest, EmitConstructor_Int) {
-  ASSERT_TRUE(gen.EmitConstructor(Expr(-12345))) << gen.error();
+  auto* expr = Expr(-12345);
+
+  GeneratorImpl& gen = Build();
+
+  ASSERT_TRUE(gen.EmitConstructor(expr)) << gen.error();
   EXPECT_EQ(gen.result(), "-12345");
 }
 
 TEST_F(WgslGeneratorImplTest, EmitConstructor_UInt) {
-  ASSERT_TRUE(gen.EmitConstructor(Expr(56779u))) << gen.error();
+  auto* expr = Expr(56779u);
+
+  GeneratorImpl& gen = Build();
+
+  ASSERT_TRUE(gen.EmitConstructor(expr)) << gen.error();
   EXPECT_EQ(gen.result(), "56779u");
 }
 
 TEST_F(WgslGeneratorImplTest, EmitConstructor_Float) {
   // Use a number close to 1<<30 but whose decimal representation ends in 0.
-  ASSERT_TRUE(gen.EmitConstructor(Expr(static_cast<float>((1 << 30) - 4))))
-      << gen.error();
+  auto* expr = Expr(static_cast<float>((1 << 30) - 4));
+
+  GeneratorImpl& gen = Build();
+
+  ASSERT_TRUE(gen.EmitConstructor(expr)) << gen.error();
   EXPECT_EQ(gen.result(), "1073741824.0");
 }
 
 TEST_F(WgslGeneratorImplTest, EmitConstructor_Type_Float) {
-  ASSERT_TRUE(gen.EmitConstructor(Construct<f32>(Expr(-1.2e-5f))))
-      << gen.error();
+  auto* expr = Construct<f32>(Expr(-1.2e-5f));
+
+  GeneratorImpl& gen = Build();
+
+  ASSERT_TRUE(gen.EmitConstructor(expr)) << gen.error();
   EXPECT_EQ(gen.result(), "f32(-0.000012)");
 }
 
 TEST_F(WgslGeneratorImplTest, EmitConstructor_Type_Bool) {
-  ASSERT_TRUE(gen.EmitConstructor(Construct<bool>(true))) << gen.error();
+  auto* expr = Construct<bool>(true);
+
+  GeneratorImpl& gen = Build();
+
+  ASSERT_TRUE(gen.EmitConstructor(expr)) << gen.error();
   EXPECT_EQ(gen.result(), "bool(true)");
 }
 
 TEST_F(WgslGeneratorImplTest, EmitConstructor_Type_Int) {
-  ASSERT_TRUE(gen.EmitConstructor(Construct<i32>(-12345))) << gen.error();
+  auto* expr = Construct<i32>(-12345);
+
+  GeneratorImpl& gen = Build();
+
+  ASSERT_TRUE(gen.EmitConstructor(expr)) << gen.error();
   EXPECT_EQ(gen.result(), "i32(-12345)");
 }
 
 TEST_F(WgslGeneratorImplTest, EmitConstructor_Type_Uint) {
-  ASSERT_TRUE(gen.EmitConstructor(Construct<u32>(12345u))) << gen.error();
+  auto* expr = Construct<u32>(12345u);
+
+  GeneratorImpl& gen = Build();
+
+  ASSERT_TRUE(gen.EmitConstructor(expr)) << gen.error();
   EXPECT_EQ(gen.result(), "u32(12345u)");
 }
 
 TEST_F(WgslGeneratorImplTest, EmitConstructor_Type_Vec) {
-  ASSERT_TRUE(gen.EmitConstructor(vec3<f32>(1.f, 2.f, 3.f))) << gen.error();
+  auto* expr = vec3<f32>(1.f, 2.f, 3.f);
+
+  GeneratorImpl& gen = Build();
+
+  ASSERT_TRUE(gen.EmitConstructor(expr)) << gen.error();
   EXPECT_EQ(gen.result(), "vec3<f32>(1.0, 2.0, 3.0)");
 }
 
 TEST_F(WgslGeneratorImplTest, EmitConstructor_Type_Mat) {
-  ASSERT_TRUE(gen.EmitConstructor(
-      Construct(ty.mat2x3<f32>(), vec2<f32>(1.0f, 2.0f), vec2<f32>(3.0f, 4.0f),
-                vec2<f32>(5.0f, 6.0f))))
-      << gen.error();
+  auto* expr = Construct(ty.mat2x3<f32>(), vec2<f32>(1.0f, 2.0f),
+                         vec2<f32>(3.0f, 4.0f), vec2<f32>(5.0f, 6.0f));
+
+  GeneratorImpl& gen = Build();
+
+  ASSERT_TRUE(gen.EmitConstructor(expr)) << gen.error();
   EXPECT_EQ(gen.result(),
             "mat2x3<f32>(vec2<f32>(1.0, 2.0), vec2<f32>(3.0, 4.0), "
             "vec2<f32>(5.0, 6.0))");
 }
 
 TEST_F(WgslGeneratorImplTest, EmitConstructor_Type_Array) {
-  ASSERT_TRUE(gen.EmitConstructor(
-      array(ty.vec3<f32>(), 3, vec3<f32>(1.f, 2.f, 3.f),
-            vec3<f32>(4.f, 5.f, 6.f), vec3<f32>(7.f, 8.f, 9.f))))
-      << gen.error();
+  auto* expr = array(ty.vec3<f32>(), 3, vec3<f32>(1.f, 2.f, 3.f),
+                     vec3<f32>(4.f, 5.f, 6.f), vec3<f32>(7.f, 8.f, 9.f));
+
+  GeneratorImpl& gen = Build();
+
+  ASSERT_TRUE(gen.EmitConstructor(expr)) << gen.error();
   EXPECT_EQ(gen.result(),
             "array<vec3<f32>, 3>(vec3<f32>(1.0, 2.0, 3.0), "
             "vec3<f32>(4.0, 5.0, 6.0), vec3<f32>(7.0, 8.0, 9.0))");
diff --git a/src/writer/wgsl/generator_impl_continue_test.cc b/src/writer/wgsl/generator_impl_continue_test.cc
index 459bbc6..13d82a4 100644
--- a/src/writer/wgsl/generator_impl_continue_test.cc
+++ b/src/writer/wgsl/generator_impl_continue_test.cc
@@ -30,6 +30,8 @@
 TEST_F(WgslGeneratorImplTest, Emit_Continue) {
   auto* c = create<ast::ContinueStatement>();
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(c)) << gen.error();
diff --git a/src/writer/wgsl/generator_impl_discard_test.cc b/src/writer/wgsl/generator_impl_discard_test.cc
index 86d1c87..5187358 100644
--- a/src/writer/wgsl/generator_impl_discard_test.cc
+++ b/src/writer/wgsl/generator_impl_discard_test.cc
@@ -27,6 +27,8 @@
 TEST_F(WgslGeneratorImplTest, Emit_Discard) {
   auto* k = create<ast::DiscardStatement>();
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(k)) << gen.error();
diff --git a/src/writer/wgsl/generator_impl_fallthrough_test.cc b/src/writer/wgsl/generator_impl_fallthrough_test.cc
index 9b4e53c..093cbb4 100644
--- a/src/writer/wgsl/generator_impl_fallthrough_test.cc
+++ b/src/writer/wgsl/generator_impl_fallthrough_test.cc
@@ -27,6 +27,8 @@
 TEST_F(WgslGeneratorImplTest, Emit_Fallthrough) {
   auto* f = create<ast::FallthroughStatement>();
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(f)) << gen.error();
diff --git a/src/writer/wgsl/generator_impl_function_test.cc b/src/writer/wgsl/generator_impl_function_test.cc
index 21844c6..9fbca86 100644
--- a/src/writer/wgsl/generator_impl_function_test.cc
+++ b/src/writer/wgsl/generator_impl_function_test.cc
@@ -48,6 +48,8 @@
                     },
                     ast::FunctionDecorationList{});
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitFunction(func));
@@ -70,6 +72,8 @@
            },
            ast::FunctionDecorationList{});
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitFunction(func));
@@ -90,6 +94,8 @@
                         create<ast::WorkgroupDecoration>(2u, 4u, 6u),
                     });
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitFunction(func));
@@ -112,6 +118,8 @@
                create<ast::StageDecoration>(ast::PipelineStage::kFragment),
            });
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitFunction(func));
@@ -135,6 +143,8 @@
                create<ast::WorkgroupDecoration>(2u, 4u, 6u),
            });
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitFunction(func));
@@ -226,6 +236,8 @@
 
   ASSERT_TRUE(td.Determine()) << td.error();
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.Generate()) << gen.error();
   EXPECT_EQ(gen.result(), R"([[block]]
 struct Data {
diff --git a/src/writer/wgsl/generator_impl_identifier_test.cc b/src/writer/wgsl/generator_impl_identifier_test.cc
index 78f9b66..b07c97a 100644
--- a/src/writer/wgsl/generator_impl_identifier_test.cc
+++ b/src/writer/wgsl/generator_impl_identifier_test.cc
@@ -26,6 +26,8 @@
 TEST_F(WgslGeneratorImplTest, EmitIdentifierExpression_Single) {
   auto* i = Expr("glsl");
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitExpression(i)) << gen.error();
   EXPECT_EQ(gen.result(), "glsl");
 }
diff --git a/src/writer/wgsl/generator_impl_if_test.cc b/src/writer/wgsl/generator_impl_if_test.cc
index c81b5f9..4f5ae04 100644
--- a/src/writer/wgsl/generator_impl_if_test.cc
+++ b/src/writer/wgsl/generator_impl_if_test.cc
@@ -34,6 +34,8 @@
   });
   auto* i = create<ast::IfStatement>(cond, body, ast::ElseStatementList{});
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(i)) << gen.error();
@@ -56,6 +58,8 @@
       ast::ElseStatementList{
           create<ast::ElseStatement>(Expr("else_cond"), else_body)});
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(i)) << gen.error();
@@ -80,6 +84,8 @@
       cond, body,
       ast::ElseStatementList{create<ast::ElseStatement>(nullptr, else_body)});
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(i)) << gen.error();
@@ -110,6 +116,8 @@
           create<ast::ElseStatement>(nullptr, else_body_2),
       });
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(i)) << gen.error();
diff --git a/src/writer/wgsl/generator_impl_loop_test.cc b/src/writer/wgsl/generator_impl_loop_test.cc
index dc2a309..d525504 100644
--- a/src/writer/wgsl/generator_impl_loop_test.cc
+++ b/src/writer/wgsl/generator_impl_loop_test.cc
@@ -33,6 +33,8 @@
   });
   auto* l = create<ast::LoopStatement>(body, nullptr);
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(l)) << gen.error();
@@ -51,6 +53,8 @@
   });
   auto* l = create<ast::LoopStatement>(body, continuing);
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(l)) << gen.error();
diff --git a/src/writer/wgsl/generator_impl_member_accessor_test.cc b/src/writer/wgsl/generator_impl_member_accessor_test.cc
index d8c4f39..0a5e19f 100644
--- a/src/writer/wgsl/generator_impl_member_accessor_test.cc
+++ b/src/writer/wgsl/generator_impl_member_accessor_test.cc
@@ -33,6 +33,8 @@
 
   auto* expr = create<ast::MemberAccessorExpression>(str, mem);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitExpression(expr)) << gen.error();
   EXPECT_EQ(gen.result(), "str.mem");
 }
diff --git a/src/writer/wgsl/generator_impl_return_test.cc b/src/writer/wgsl/generator_impl_return_test.cc
index ba27df8..69c2151 100644
--- a/src/writer/wgsl/generator_impl_return_test.cc
+++ b/src/writer/wgsl/generator_impl_return_test.cc
@@ -31,6 +31,8 @@
 TEST_F(WgslGeneratorImplTest, Emit_Return) {
   auto* r = create<ast::ReturnStatement>();
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(r)) << gen.error();
@@ -41,6 +43,8 @@
   auto* expr = Expr("expr");
   auto* r = create<ast::ReturnStatement>(expr);
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(r)) << gen.error();
diff --git a/src/writer/wgsl/generator_impl_switch_test.cc b/src/writer/wgsl/generator_impl_switch_test.cc
index 48b2b83..4e2e7d2 100644
--- a/src/writer/wgsl/generator_impl_switch_test.cc
+++ b/src/writer/wgsl/generator_impl_switch_test.cc
@@ -53,6 +53,8 @@
   auto* cond = Expr("cond");
   auto* s = create<ast::SwitchStatement>(cond, body);
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(s)) << gen.error();
diff --git a/src/writer/wgsl/generator_impl_test.cc b/src/writer/wgsl/generator_impl_test.cc
index c3661d5..31312fa 100644
--- a/src/writer/wgsl/generator_impl_test.cc
+++ b/src/writer/wgsl/generator_impl_test.cc
@@ -33,6 +33,8 @@
   mod->AddFunction(Func("my_func", ast::VariableList{}, ty.void_,
                         ast::StatementList{}, ast::FunctionDecorationList{}));
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.Generate()) << gen.error();
   EXPECT_EQ(gen.result(), R"(fn my_func() -> void {
 }
diff --git a/src/writer/wgsl/generator_impl_type_test.cc b/src/writer/wgsl/generator_impl_type_test.cc
index f67e8eb..9e229d6 100644
--- a/src/writer/wgsl/generator_impl_type_test.cc
+++ b/src/writer/wgsl/generator_impl_type_test.cc
@@ -50,11 +50,15 @@
 TEST_F(WgslGeneratorImplTest, EmitType_Alias) {
   auto* alias = ty.alias("alias", ty.f32);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(alias)) << gen.error();
   EXPECT_EQ(gen.result(), "alias");
 }
 
 TEST_F(WgslGeneratorImplTest, EmitType_Array) {
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(ty.array<bool, 4>())) << gen.error();
   EXPECT_EQ(gen.result(), "array<bool, 4>");
 }
@@ -70,6 +74,8 @@
 
   type::AccessControl a(ast::AccessControl::kReadOnly, s);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(&a)) << gen.error();
   EXPECT_EQ(gen.result(), "[[access(read)]]\nS");
 }
@@ -85,6 +91,8 @@
 
   type::AccessControl a(ast::AccessControl::kReadWrite, s);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(&a)) << gen.error();
   EXPECT_EQ(gen.result(), "[[access(read_write)]]\nS");
 }
@@ -95,6 +103,8 @@
                     create<ast::StrideDecoration>(16u),
                 });
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(&a)) << gen.error();
   EXPECT_EQ(gen.result(), "[[stride(16)]] array<bool, 4>");
 }
@@ -106,6 +116,8 @@
                     create<ast::StrideDecoration>(32u),
                 });
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(&a)) << gen.error();
   EXPECT_EQ(gen.result(), "[[stride(16)]] [[stride(32)]] array<bool, 4>");
 }
@@ -113,26 +125,36 @@
 TEST_F(WgslGeneratorImplTest, EmitType_RuntimeArray) {
   type::Array a(ty.bool_, 0, ast::ArrayDecorationList{});
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(&a)) << gen.error();
   EXPECT_EQ(gen.result(), "array<bool>");
 }
 
 TEST_F(WgslGeneratorImplTest, EmitType_Bool) {
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(ty.bool_)) << gen.error();
   EXPECT_EQ(gen.result(), "bool");
 }
 
 TEST_F(WgslGeneratorImplTest, EmitType_F32) {
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(ty.f32)) << gen.error();
   EXPECT_EQ(gen.result(), "f32");
 }
 
 TEST_F(WgslGeneratorImplTest, EmitType_I32) {
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(ty.i32)) << gen.error();
   EXPECT_EQ(gen.result(), "i32");
 }
 
 TEST_F(WgslGeneratorImplTest, EmitType_Matrix) {
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(ty.mat2x3<f32>())) << gen.error();
   EXPECT_EQ(gen.result(), "mat2x3<f32>");
 }
@@ -140,6 +162,8 @@
 TEST_F(WgslGeneratorImplTest, EmitType_Pointer) {
   type::Pointer p(ty.f32, ast::StorageClass::kWorkgroup);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(&p)) << gen.error();
   EXPECT_EQ(gen.result(), "ptr<workgroup, f32>");
 }
@@ -151,6 +175,8 @@
       ast::StructDecorationList{});
 
   auto* s = ty.struct_("S", str);
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(s)) << gen.error();
   EXPECT_EQ(gen.result(), "S");
 }
@@ -162,6 +188,8 @@
       ast::StructDecorationList{});
 
   auto* s = ty.struct_("S", str);
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitStructType(s)) << gen.error();
   EXPECT_EQ(gen.result(), R"(struct S {
   a : i32;
@@ -181,6 +209,8 @@
       decos);
 
   auto* s = ty.struct_("S", str);
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitStructType(s)) << gen.error();
   EXPECT_EQ(gen.result(), R"([[block]]
 struct S {
@@ -192,16 +222,22 @@
 }
 
 TEST_F(WgslGeneratorImplTest, EmitType_U32) {
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(ty.u32)) << gen.error();
   EXPECT_EQ(gen.result(), "u32");
 }
 
 TEST_F(WgslGeneratorImplTest, EmitType_Vector) {
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(ty.vec3<f32>())) << gen.error();
   EXPECT_EQ(gen.result(), "vec3<f32>");
 }
 
 TEST_F(WgslGeneratorImplTest, EmitType_Void) {
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(ty.void_)) << gen.error();
   EXPECT_EQ(gen.result(), "void");
 }
@@ -221,6 +257,8 @@
 
   type::DepthTexture d(param.dim);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(&d)) << gen.error();
   EXPECT_EQ(gen.result(), param.name);
 }
@@ -240,6 +278,8 @@
 
   type::SampledTexture t(param.dim, ty.f32);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(&t)) << gen.error();
   EXPECT_EQ(gen.result(), std::string(param.name) + "<f32>");
 }
@@ -249,6 +289,8 @@
 
   type::SampledTexture t(param.dim, ty.i32);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(&t)) << gen.error();
   EXPECT_EQ(gen.result(), std::string(param.name) + "<i32>");
 }
@@ -258,6 +300,8 @@
 
   type::SampledTexture t(param.dim, ty.u32);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(&t)) << gen.error();
   EXPECT_EQ(gen.result(), std::string(param.name) + "<u32>");
 }
@@ -279,6 +323,8 @@
 
   type::MultisampledTexture t(param.dim, ty.f32);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(&t)) << gen.error();
   EXPECT_EQ(gen.result(), std::string(param.name) + "<f32>");
 }
@@ -288,6 +334,8 @@
 
   type::MultisampledTexture t(param.dim, ty.i32);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(&t)) << gen.error();
   EXPECT_EQ(gen.result(), std::string(param.name) + "<i32>");
 }
@@ -297,6 +345,8 @@
 
   type::MultisampledTexture t(param.dim, ty.u32);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(&t)) << gen.error();
   EXPECT_EQ(gen.result(), std::string(param.name) + "<u32>");
 }
@@ -323,6 +373,8 @@
   type::StorageTexture t(param.dim, param.fmt);
   type::AccessControl ac(param.access, &t);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(&ac)) << gen.error();
   EXPECT_EQ(gen.result(), param.name);
 }
@@ -383,6 +435,8 @@
 TEST_P(WgslGenerator_ImageFormatTest, EmitType_StorageTexture_ImageFormat) {
   auto param = GetParam();
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitImageFormat(param.fmt)) << gen.error();
   EXPECT_EQ(gen.result(), param.name);
 }
@@ -430,6 +484,8 @@
 TEST_F(WgslGeneratorImplTest, EmitType_Sampler) {
   type::Sampler sampler(type::SamplerKind::kSampler);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(&sampler)) << gen.error();
   EXPECT_EQ(gen.result(), "sampler");
 }
@@ -437,6 +493,8 @@
 TEST_F(WgslGeneratorImplTest, EmitType_SamplerComparison) {
   type::Sampler sampler(type::SamplerKind::kComparisonSampler);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitType(&sampler)) << gen.error();
   EXPECT_EQ(gen.result(), "sampler_comparison");
 }
diff --git a/src/writer/wgsl/generator_impl_unary_op_test.cc b/src/writer/wgsl/generator_impl_unary_op_test.cc
index 16aa616..8ff75a3 100644
--- a/src/writer/wgsl/generator_impl_unary_op_test.cc
+++ b/src/writer/wgsl/generator_impl_unary_op_test.cc
@@ -41,6 +41,8 @@
   auto* expr = Expr("expr");
   auto* op = create<ast::UnaryOpExpression>(params.op, expr);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitExpression(op)) << gen.error();
   EXPECT_EQ(gen.result(), std::string(params.name) + "(expr)");
 }
diff --git a/src/writer/wgsl/generator_impl_variable_decl_statement_test.cc b/src/writer/wgsl/generator_impl_variable_decl_statement_test.cc
index c1c3229..c774920 100644
--- a/src/writer/wgsl/generator_impl_variable_decl_statement_test.cc
+++ b/src/writer/wgsl/generator_impl_variable_decl_statement_test.cc
@@ -35,6 +35,8 @@
 
   auto* stmt = create<ast::VariableDeclStatement>(var);
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(stmt)) << gen.error();
@@ -50,6 +52,8 @@
 
   auto* stmt = create<ast::VariableDeclStatement>(var);
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(stmt)) << gen.error();
@@ -61,6 +65,8 @@
 
   auto* stmt = create<ast::VariableDeclStatement>(var);
 
+  GeneratorImpl& gen = Build();
+
   gen.increment_indent();
 
   ASSERT_TRUE(gen.EmitStatement(stmt)) << gen.error();
diff --git a/src/writer/wgsl/generator_impl_variable_test.cc b/src/writer/wgsl/generator_impl_variable_test.cc
index 9a8e9fc..dd105e7 100644
--- a/src/writer/wgsl/generator_impl_variable_test.cc
+++ b/src/writer/wgsl/generator_impl_variable_test.cc
@@ -36,6 +36,8 @@
 TEST_F(WgslGeneratorImplTest, EmitVariable) {
   auto* v = Var("a", ast::StorageClass::kNone, ty.f32);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitVariable(v)) << gen.error();
   EXPECT_EQ(gen.result(), R"(var a : f32;
 )");
@@ -44,6 +46,8 @@
 TEST_F(WgslGeneratorImplTest, EmitVariable_StorageClass) {
   auto* v = Var("a", ast::StorageClass::kInput, ty.f32);
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitVariable(v)) << gen.error();
   EXPECT_EQ(gen.result(), R"(var<in> a : f32;
 )");
@@ -55,6 +59,8 @@
                     create<ast::LocationDecoration>(2),
                 });
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitVariable(v)) << gen.error();
   EXPECT_EQ(gen.result(), R"([[location(2)]] var a : f32;
 )");
@@ -70,6 +76,8 @@
                     create<ast::ConstantIdDecoration>(42),
                 });
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitVariable(v)) << gen.error();
   EXPECT_EQ(
       gen.result(),
@@ -81,6 +89,8 @@
   auto* v = Var("a", ast::StorageClass::kNone, ty.f32, Expr("initializer"),
                 ast::VariableDecorationList{});
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitVariable(v)) << gen.error();
   EXPECT_EQ(gen.result(), R"(var a : f32 = initializer;
 )");
@@ -90,6 +100,8 @@
   auto* v = Const("a", ast::StorageClass::kNone, ty.f32, Expr("initializer"),
                   ast::VariableDecorationList{});
 
+  GeneratorImpl& gen = Build();
+
   ASSERT_TRUE(gen.EmitVariable(v)) << gen.error();
   EXPECT_EQ(gen.result(), R"(const a : f32 = initializer;
 )");
diff --git a/src/writer/wgsl/test_helper.h b/src/writer/wgsl/test_helper.h
index 8ef37bd..6507d32 100644
--- a/src/writer/wgsl/test_helper.h
+++ b/src/writer/wgsl/test_helper.h
@@ -31,14 +31,27 @@
 template <typename BASE>
 class TestHelperBase : public BASE, public ast::BuilderWithModule {
  public:
-  TestHelperBase() : td(mod), gen(mod) {}
+  TestHelperBase() : td(mod) {}
 
   ~TestHelperBase() = default;
 
+  /// Builds and returns a GeneratorImpl from the module.
+  /// @note The generator is only built once. Multiple calls to Build() will
+  /// return the same GeneratorImpl without rebuilding.
+  /// @return the built generator
+  GeneratorImpl& Build() {
+    if (gen_) {
+      return *gen_;
+    }
+    gen_ = std::make_unique<GeneratorImpl>(mod);
+    return *gen_;
+  }
+
   /// The type determiner
   TypeDeterminer td;
-  /// The generator
-  GeneratorImpl gen;
+
+ private:
+  std::unique_ptr<GeneratorImpl> gen_;
 };
 using TestHelper = TestHelperBase<testing::Test>;