tint/writer/spirv: Create Module class

Move the generic code for building up a SPIR-V module from Builder to
a new Module class. This can then be reused by the new IR-based SPIR-V
writer.

Switches to naming of methods to camel case to bring in line with the
rest of the codebase.

Bug: tint:1906
Change-Id: I7775edff6fe56328c6562559c016a19097b50805
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/131340
Reviewed-by: Dan Sinclair <dsinclair@chromium.org>
Commit-Queue: James Price <jrprice@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
diff --git a/src/tint/writer/spirv/binary_writer.cc b/src/tint/writer/spirv/binary_writer.cc
index 69ac353..4952bdb 100644
--- a/src/tint/writer/spirv/binary_writer.cc
+++ b/src/tint/writer/spirv/binary_writer.cc
@@ -28,9 +28,9 @@
 
 BinaryWriter::~BinaryWriter() = default;
 
-void BinaryWriter::WriteBuilder(Builder* builder) {
-    out_.reserve(builder->total_size());
-    builder->iterate([this](const Instruction& inst) { this->process_instruction(inst); });
+void BinaryWriter::WriteModule(const Module* module) {
+    out_.reserve(module->TotalSize());
+    module->Iterate([this](const Instruction& inst) { this->process_instruction(inst); });
 }
 
 void BinaryWriter::WriteInstruction(const Instruction& inst) {
diff --git a/src/tint/writer/spirv/binary_writer.h b/src/tint/writer/spirv/binary_writer.h
index e1e7f68..0b1c234 100644
--- a/src/tint/writer/spirv/binary_writer.h
+++ b/src/tint/writer/spirv/binary_writer.h
@@ -17,11 +17,11 @@
 
 #include <vector>
 
-#include "src/tint/writer/spirv/builder.h"
+#include "src/tint/writer/spirv/module.h"
 
 namespace tint::writer::spirv {
 
-/// Writer to convert from builder to SPIR-V binary
+/// Writer to convert from module to SPIR-V binary.
 class BinaryWriter {
   public:
     /// Constructor
@@ -32,11 +32,10 @@
     /// @param bound the bound to output
     void WriteHeader(uint32_t bound);
 
-    /// Writes the given builder data into a binary. Note, this does not emit
-    /// the SPIR-V header. You **must** call WriteHeader() before WriteBuilder()
-    /// if you want the SPIR-V to be emitted.
-    /// @param builder the builder to assemble from
-    void WriteBuilder(Builder* builder);
+    /// Writes the given module data into a binary. Note, this does not emit the SPIR-V header. You
+    /// **must** call WriteHeader() before WriteModule() if you want the SPIR-V to be emitted.
+    /// @param module the module to assemble from
+    void WriteModule(const Module* module);
 
     /// Writes the given instruction into the binary.
     /// @param inst the instruction to assemble
diff --git a/src/tint/writer/spirv/binary_writer_test.cc b/src/tint/writer/spirv/binary_writer_test.cc
index 11812cf..c043b25 100644
--- a/src/tint/writer/spirv/binary_writer_test.cc
+++ b/src/tint/writer/spirv/binary_writer_test.cc
@@ -33,11 +33,11 @@
 }
 
 TEST_F(BinaryWriterTest, Float) {
-    spirv::Builder& b = Build();
+    Module m;
 
-    b.push_annot(spv::Op::OpKill, {Operand(2.4f)});
+    m.PushAnnot(spv::Op::OpKill, {Operand(2.4f)});
     BinaryWriter bw;
-    bw.WriteBuilder(&b);
+    bw.WriteModule(&m);
 
     auto res = bw.result();
     ASSERT_EQ(res.size(), 2u);
@@ -47,11 +47,11 @@
 }
 
 TEST_F(BinaryWriterTest, Int) {
-    spirv::Builder& b = Build();
+    Module m;
 
-    b.push_annot(spv::Op::OpKill, {Operand(2u)});
+    m.PushAnnot(spv::Op::OpKill, {Operand(2u)});
     BinaryWriter bw;
-    bw.WriteBuilder(&b);
+    bw.WriteModule(&m);
 
     auto res = bw.result();
     ASSERT_EQ(res.size(), 2u);
@@ -59,11 +59,11 @@
 }
 
 TEST_F(BinaryWriterTest, String) {
-    spirv::Builder& b = Build();
+    Module m;
 
-    b.push_annot(spv::Op::OpKill, {Operand("my_string")});
+    m.PushAnnot(spv::Op::OpKill, {Operand("my_string")});
     BinaryWriter bw;
-    bw.WriteBuilder(&b);
+    bw.WriteModule(&m);
 
     auto res = bw.result();
     ASSERT_EQ(res.size(), 4u);
@@ -84,11 +84,11 @@
 }
 
 TEST_F(BinaryWriterTest, String_Multiple4Length) {
-    spirv::Builder& b = Build();
+    Module m;
 
-    b.push_annot(spv::Op::OpKill, {Operand("mystring")});
+    m.PushAnnot(spv::Op::OpKill, {Operand("mystring")});
     BinaryWriter bw;
-    bw.WriteBuilder(&b);
+    bw.WriteModule(&m);
 
     auto res = bw.result();
     ASSERT_EQ(res.size(), 4u);
diff --git a/src/tint/writer/spirv/builder.cc b/src/tint/writer/spirv/builder.cc
index b3ae005..40ab2a4 100644
--- a/src/tint/writer/spirv/builder.cc
+++ b/src/tint/writer/spirv/builder.cc
@@ -58,15 +58,6 @@
 
 const char kGLSLstd450[] = "GLSL.std.450";
 
-uint32_t size_of(const InstructionList& instructions) {
-    uint32_t size = 0;
-    for (const auto& inst : instructions) {
-        size += inst.word_length();
-    }
-
-    return size;
-}
-
 uint32_t pipeline_stage_to_execution_model(ast::PipelineStage stage) {
     SpvExecutionModel model = SpvExecutionModelVertex;
 
@@ -274,10 +265,10 @@
         return false;
     }
 
-    push_capability(SpvCapabilityShader);
+    module_.PushCapability(SpvCapabilityShader);
 
-    push_memory_model(spv::Op::OpMemoryModel,
-                      {U32Operand(SpvAddressingModelLogical), U32Operand(SpvMemoryModelGLSL450)});
+    module_.PushMemoryModel(spv::Op::OpMemoryModel, {U32Operand(SpvAddressingModelLogical),
+                                                     U32Operand(SpvMemoryModelGLSL450)});
 
     for (auto ext : builder_.Sem().Module()->Extensions()) {
         GenerateExtension(ext);
@@ -325,85 +316,21 @@
 }
 
 Operand Builder::result_op() {
-    return Operand(next_id());
-}
-
-uint32_t Builder::total_size() const {
-    // The 5 covers the magic, version, generator, id bound and reserved.
-    uint32_t size = 5;
-
-    size += size_of(capabilities_);
-    size += size_of(extensions_);
-    size += size_of(ext_imports_);
-    size += size_of(memory_model_);
-    size += size_of(entry_points_);
-    size += size_of(execution_modes_);
-    size += size_of(debug_);
-    size += size_of(annotations_);
-    size += size_of(types_);
-    for (const auto& func : functions_) {
-        size += func.word_length();
-    }
-
-    return size;
-}
-
-void Builder::iterate(std::function<void(const Instruction&)> cb) const {
-    for (const auto& inst : capabilities_) {
-        cb(inst);
-    }
-    for (const auto& inst : extensions_) {
-        cb(inst);
-    }
-    for (const auto& inst : ext_imports_) {
-        cb(inst);
-    }
-    for (const auto& inst : memory_model_) {
-        cb(inst);
-    }
-    for (const auto& inst : entry_points_) {
-        cb(inst);
-    }
-    for (const auto& inst : execution_modes_) {
-        cb(inst);
-    }
-    for (const auto& inst : debug_) {
-        cb(inst);
-    }
-    for (const auto& inst : annotations_) {
-        cb(inst);
-    }
-    for (const auto& inst : types_) {
-        cb(inst);
-    }
-    for (const auto& func : functions_) {
-        func.iterate(cb);
-    }
-}
-
-void Builder::push_capability(uint32_t cap) {
-    if (capability_set_.count(cap) == 0) {
-        capability_set_.insert(cap);
-        capabilities_.push_back(Instruction{spv::Op::OpCapability, {Operand(cap)}});
-    }
-}
-
-void Builder::push_extension(const char* extension) {
-    extensions_.push_back(Instruction{spv::Op::OpExtension, {Operand(extension)}});
+    return Operand(module_.NextId());
 }
 
 bool Builder::GenerateExtension(builtin::Extension extension) {
     switch (extension) {
         case builtin::Extension::kChromiumExperimentalDp4A:
-            push_extension("SPV_KHR_integer_dot_product");
-            push_capability(SpvCapabilityDotProductKHR);
-            push_capability(SpvCapabilityDotProductInput4x8BitPackedKHR);
+            module_.PushExtension("SPV_KHR_integer_dot_product");
+            module_.PushCapability(SpvCapabilityDotProductKHR);
+            module_.PushCapability(SpvCapabilityDotProductInput4x8BitPackedKHR);
             break;
         case builtin::Extension::kF16:
-            push_capability(SpvCapabilityFloat16);
-            push_capability(SpvCapabilityUniformAndStorageBuffer16BitAccess);
-            push_capability(SpvCapabilityStorageBuffer16BitAccess);
-            push_capability(SpvCapabilityStorageInputOutput16);
+            module_.PushCapability(SpvCapabilityFloat16);
+            module_.PushCapability(SpvCapabilityUniformAndStorageBuffer16BitAccess);
+            module_.PushCapability(SpvCapabilityStorageBuffer16BitAccess);
+            module_.PushCapability(SpvCapabilityStorageInputOutput16);
             break;
         default:
             return false;
@@ -517,7 +444,7 @@
 
         operands.push_back(Operand(var_id));
     }
-    push_entry_point(spv::Op::OpEntryPoint, operands);
+    module_.PushEntryPoint(spv::Op::OpEntryPoint, operands);
 
     return true;
 }
@@ -527,8 +454,8 @@
 
     // WGSL fragment shader origin is upper left
     if (func->PipelineStage() == ast::PipelineStage::kFragment) {
-        push_execution_mode(spv::Op::OpExecutionMode,
-                            {Operand(id), U32Operand(SpvExecutionModeOriginUpperLeft)});
+        module_.PushExecutionMode(spv::Op::OpExecutionMode,
+                                  {Operand(id), U32Operand(SpvExecutionModeOriginUpperLeft)});
     } else if (func->PipelineStage() == ast::PipelineStage::kCompute) {
         auto& wgsize = func_sem->WorkgroupSize();
 
@@ -539,7 +466,7 @@
                 "transform";
             return false;
         }
-        push_execution_mode(
+        module_.PushExecutionMode(
             spv::Op::OpExecutionMode,
             {Operand(id), U32Operand(SpvExecutionModeLocalSize),  //
              Operand(wgsize[0].value()), Operand(wgsize[1].value()), Operand(wgsize[2].value())});
@@ -548,8 +475,8 @@
     for (auto it : func_sem->TransitivelyReferencedBuiltinVariables()) {
         auto builtin = builder_.Sem().Get(it.second)->Value();
         if (builtin == builtin::BuiltinValue::kFragDepth) {
-            push_execution_mode(spv::Op::OpExecutionMode,
-                                {Operand(id), U32Operand(SpvExecutionModeDepthReplacing)});
+            module_.PushExecutionMode(spv::Op::OpExecutionMode,
+                                      {Operand(id), U32Operand(SpvExecutionModeDepthReplacing)});
         }
     }
 
@@ -599,7 +526,7 @@
     auto func_op = result_op();
     auto func_id = std::get<uint32_t>(func_op);
 
-    push_debug(spv::Op::OpName, {Operand(func_id), Operand(func_ast->name->symbol.Name())});
+    module_.PushDebug(spv::Op::OpName, {Operand(func_id), Operand(func_ast->name->symbol.Name())});
 
     auto ret_id = GenerateTypeIfNeeded(func->ReturnType());
     if (ret_id == 0) {
@@ -623,15 +550,18 @@
             return false;
         }
 
-        push_debug(spv::Op::OpName,
-                   {Operand(param_id), Operand(param->Declaration()->name->symbol.Name())});
+        module_.PushDebug(spv::Op::OpName,
+                          {Operand(param_id), Operand(param->Declaration()->name->symbol.Name())});
         params.push_back(
             Instruction{spv::Op::OpFunctionParameter, {Operand(param_type_id), param_op}});
 
         RegisterVariable(param, param_id);
     }
 
-    push_function(Function{definition_inst, result_op(), std::move(params)});
+    // Start a new function.
+    current_function_ = Function{definition_inst, result_op(), std::move(params)};
+    current_label_id_ = current_function_.label_id();
+    TINT_DEFER(current_function_ = Function());
 
     for (auto* stmt : func_ast->body->statements) {
         if (!GenerateStatement(stmt)) {
@@ -659,6 +589,9 @@
 
     func_symbol_to_id_[func_ast->name->symbol] = func_id;
 
+    // Add the function to the module.
+    module_.PushFunction(std::move(current_function_));
+
     return true;
 }
 
@@ -681,7 +614,7 @@
             ops.push_back(Operand(param_type_id));
         }
 
-        push_type(spv::Op::OpTypeFunction, std::move(ops));
+        module_.PushType(spv::Op::OpTypeFunction, std::move(ops));
         return func_type_id;
     });
 }
@@ -721,7 +654,7 @@
         return false;
     }
 
-    push_debug(spv::Op::OpName, {Operand(var_id), Operand(v->name->symbol.Name())});
+    module_.PushDebug(spv::Op::OpName, {Operand(var_id), Operand(v->name->symbol.Name())});
 
     // TODO(dsinclair) We could detect if the initializer is fully const and emit
     // an initializer value for the variable instead of doing the OpLoad.
@@ -782,7 +715,7 @@
         return false;
     }
 
-    push_debug(spv::Op::OpName, {Operand(var_id), Operand(v->name->symbol.Name())});
+    module_.PushDebug(spv::Op::OpName, {Operand(var_id), Operand(v->name->symbol.Name())});
 
     OperandList ops = {Operand(type_id), result, U32Operand(ConvertAddressSpace(sc))};
 
@@ -795,12 +728,12 @@
             auto access = st ? st->access() : sem->Access();
             switch (access) {
                 case builtin::Access::kWrite:
-                    push_annot(spv::Op::OpDecorate,
-                               {Operand(var_id), U32Operand(SpvDecorationNonReadable)});
+                    module_.PushAnnot(spv::Op::OpDecorate,
+                                      {Operand(var_id), U32Operand(SpvDecorationNonReadable)});
                     break;
                 case builtin::Access::kRead:
-                    push_annot(spv::Op::OpDecorate,
-                               {Operand(var_id), U32Operand(SpvDecorationNonWritable)});
+                    module_.PushAnnot(spv::Op::OpDecorate,
+                                      {Operand(var_id), U32Operand(SpvDecorationNonWritable)});
                     break;
                 case builtin::Access::kUndefined:
                 case builtin::Access::kReadWrite:
@@ -826,21 +759,22 @@
         }
     }
 
-    push_type(spv::Op::OpVariable, std::move(ops));
+    module_.PushType(spv::Op::OpVariable, std::move(ops));
 
     for (auto* attr : v->attributes) {
         bool ok = Switch(
             attr,
             [&](const ast::BuiltinAttribute* builtin_attr) {
                 auto builtin = builder_.Sem().Get(builtin_attr)->Value();
-                push_annot(spv::Op::OpDecorate,
-                           {Operand(var_id), U32Operand(SpvDecorationBuiltIn),
-                            U32Operand(ConvertBuiltin(builtin, sem->AddressSpace()))});
+                module_.PushAnnot(spv::Op::OpDecorate,
+                                  {Operand(var_id), U32Operand(SpvDecorationBuiltIn),
+                                   U32Operand(ConvertBuiltin(builtin, sem->AddressSpace()))});
                 return true;
             },
             [&](const ast::LocationAttribute*) {
-                push_annot(spv::Op::OpDecorate, {Operand(var_id), U32Operand(SpvDecorationLocation),
-                                                 Operand(sem->Location().value())});
+                module_.PushAnnot(spv::Op::OpDecorate,
+                                  {Operand(var_id), U32Operand(SpvDecorationLocation),
+                                   Operand(sem->Location().value())});
                 return true;
             },
             [&](const ast::InterpolateAttribute* interpolate) {
@@ -860,19 +794,20 @@
                 return true;
             },
             [&](const ast::InvariantAttribute*) {
-                push_annot(spv::Op::OpDecorate,
-                           {Operand(var_id), U32Operand(SpvDecorationInvariant)});
+                module_.PushAnnot(spv::Op::OpDecorate,
+                                  {Operand(var_id), U32Operand(SpvDecorationInvariant)});
                 return true;
             },
             [&](const ast::BindingAttribute*) {
                 auto bp = sem->BindingPoint();
-                push_annot(spv::Op::OpDecorate, {Operand(var_id), U32Operand(SpvDecorationBinding),
-                                                 Operand(bp->binding)});
+                module_.PushAnnot(
+                    spv::Op::OpDecorate,
+                    {Operand(var_id), U32Operand(SpvDecorationBinding), Operand(bp->binding)});
                 return true;
             },
             [&](const ast::GroupAttribute*) {
                 auto bp = sem->BindingPoint();
-                push_annot(
+                module_.PushAnnot(
                     spv::Op::OpDecorate,
                     {Operand(var_id), U32Operand(SpvDecorationDescriptorSet), Operand(bp->group)});
                 return true;
@@ -1232,7 +1167,7 @@
     auto result = result_op();
     auto id = std::get<uint32_t>(result);
 
-    push_ext_import(spv::Op::OpExtInstImport, {result, Operand(kGLSLstd450)});
+    module_.PushExtImport(spv::Op::OpExtInstImport, {result, Operand(kGLSLstd450)});
 
     // Remember it for later.
     import_name_to_id_[kGLSLstd450] = id;
@@ -1404,9 +1339,9 @@
                     if (idx_id == 0) {
                         return 0;
                     }
-                    push_type(spv::Op::OpSpecConstantOp,
-                              {Operand(value_type_id), extract, U32Operand(SpvOpCompositeExtract),
-                               Operand(id), Operand(idx_id)});
+                    module_.PushType(spv::Op::OpSpecConstantOp, {Operand(value_type_id), extract,
+                                                                 U32Operand(SpvOpCompositeExtract),
+                                                                 Operand(id), Operand(idx_id)});
 
                     result_is_spec_composite = true;
                 }
@@ -1438,9 +1373,9 @@
         ops[kOpsResultIdx] = result;
 
         if (result_is_spec_composite) {
-            push_type(spv::Op::OpSpecConstantComposite, ops);
+            module_.PushType(spv::Op::OpSpecConstantComposite, ops);
         } else if (result_is_constant_composite) {
-            push_type(spv::Op::OpConstantComposite, ops);
+            module_.PushType(spv::Op::OpConstantComposite, ops);
         } else {
             if (!push_function_inst(spv::Op::OpCompositeConstruct, ops)) {
                 return 0;
@@ -1674,13 +1609,13 @@
         }
 
         auto& global_scope = scope_stack_[0];
-        return utils::GetOrCreate(global_scope.type_init_to_id_, OperandListKey{ops},
-                                  [&]() -> uint32_t {
-                                      auto result = result_op();
-                                      ops[kOpsResultIdx] = result;
-                                      push_type(spv::Op::OpConstantComposite, std::move(ops));
-                                      return std::get<uint32_t>(result);
-                                  });
+        return utils::GetOrCreate(
+            global_scope.type_init_to_id_, OperandListKey{ops}, [&]() -> uint32_t {
+                auto result = result_op();
+                ops[kOpsResultIdx] = result;
+                module_.PushType(spv::Op::OpConstantComposite, std::move(ops));
+                return std::get<uint32_t>(result);
+            });
     };
 
     return Switch(
@@ -1762,28 +1697,31 @@
 
     switch (constant.kind) {
         case ScalarConstant::Kind::kU32: {
-            push_type(spv::Op::OpConstant, {Operand(type_id), result, Operand(constant.value.u32)});
+            module_.PushType(spv::Op::OpConstant,
+                             {Operand(type_id), result, Operand(constant.value.u32)});
             break;
         }
         case ScalarConstant::Kind::kI32: {
-            push_type(spv::Op::OpConstant,
-                      {Operand(type_id), result, U32Operand(constant.value.i32)});
+            module_.PushType(spv::Op::OpConstant,
+                             {Operand(type_id), result, U32Operand(constant.value.i32)});
             break;
         }
         case ScalarConstant::Kind::kF32: {
-            push_type(spv::Op::OpConstant, {Operand(type_id), result, Operand(constant.value.f32)});
+            module_.PushType(spv::Op::OpConstant,
+                             {Operand(type_id), result, Operand(constant.value.f32)});
             break;
         }
         case ScalarConstant::Kind::kF16: {
-            push_type(spv::Op::OpConstant, {Operand(type_id), result,
-                                            U32Operand(constant.value.f16.bits_representation)});
+            module_.PushType(
+                spv::Op::OpConstant,
+                {Operand(type_id), result, U32Operand(constant.value.f16.bits_representation)});
             break;
         }
         case ScalarConstant::Kind::kBool: {
             if (constant.value.b) {
-                push_type(spv::Op::OpConstantTrue, {Operand(type_id), result});
+                module_.PushType(spv::Op::OpConstantTrue, {Operand(type_id), result});
             } else {
-                push_type(spv::Op::OpConstantFalse, {Operand(type_id), result});
+                module_.PushType(spv::Op::OpConstantFalse, {Operand(type_id), result});
             }
             break;
         }
@@ -1802,7 +1740,7 @@
     return utils::GetOrCreate(const_null_to_id_, type, [&] {
         auto result = result_op();
 
-        push_type(spv::Op::OpConstantNull, {Operand(type_id), result});
+        module_.PushType(spv::Op::OpConstantNull, {Operand(type_id), result});
 
         return std::get<uint32_t>(result);
     });
@@ -1825,7 +1763,7 @@
         for (uint32_t i = 0; i < type->Width(); i++) {
             ops.push_back(Operand(value_id));
         }
-        push_type(spv::Op::OpConstantComposite, ops);
+        module_.PushType(spv::Op::OpConstantComposite, ops);
 
         const_splat_to_id_[key] = result_id;
         return result_id;
@@ -2297,11 +2235,11 @@
     }
 
     if (builtin->IsFineDerivative() || builtin->IsCoarseDerivative()) {
-        push_capability(SpvCapabilityDerivativeControl);
+        module_.PushCapability(SpvCapabilityDerivativeControl);
     }
 
     if (builtin->IsImageQuery()) {
-        push_capability(SpvCapabilityImageQuery);
+        module_.PushCapability(SpvCapabilityImageQuery);
     }
 
     if (builtin->IsTexture()) {
@@ -3290,7 +3228,8 @@
             // We need to create the sampled image type and cache the result.
             auto sampled_image_type = result_op();
             auto texture_type_id = GenerateTypeIfNeeded(texture_type);
-            push_type(spv::Op::OpTypeSampledImage, {sampled_image_type, Operand(texture_type_id)});
+            module_.PushType(spv::Op::OpTypeSampledImage,
+                             {sampled_image_type, Operand(texture_type_id)});
             return std::get<uint32_t>(sampled_image_type);
         });
 
@@ -3357,7 +3296,7 @@
 
     // if there are no more else statements we branch on false to the merge
     // block otherwise we branch to the false block
-    auto false_block_id = else_stmt ? next_id() : merge_block_id;
+    auto false_block_id = else_stmt ? module_.NextId() : merge_block_id;
 
     if (!push_function_inst(spv::Op::OpBranchConditional,
                             {Operand(cond_id), Operand(true_block_id), Operand(false_block_id)})) {
@@ -3677,19 +3616,19 @@
                 return GenerateArrayType(arr, result);
             },
             [&](const type::Bool*) {
-                push_type(spv::Op::OpTypeBool, {result});
+                module_.PushType(spv::Op::OpTypeBool, {result});
                 return true;
             },
             [&](const type::F32*) {
-                push_type(spv::Op::OpTypeFloat, {result, Operand(32u)});
+                module_.PushType(spv::Op::OpTypeFloat, {result, Operand(32u)});
                 return true;
             },
             [&](const type::F16*) {
-                push_type(spv::Op::OpTypeFloat, {result, Operand(16u)});
+                module_.PushType(spv::Op::OpTypeFloat, {result, Operand(16u)});
                 return true;
             },
             [&](const type::I32*) {
-                push_type(spv::Op::OpTypeInt, {result, Operand(32u), Operand(1u)});
+                module_.PushType(spv::Op::OpTypeInt, {result, Operand(32u), Operand(1u)});
                 return true;
             },
             [&](const type::Matrix* mat) {  //
@@ -3705,14 +3644,14 @@
                 return GenerateStructType(str, result);
             },
             [&](const type::U32*) {
-                push_type(spv::Op::OpTypeInt, {result, Operand(32u), Operand(0u)});
+                module_.PushType(spv::Op::OpTypeInt, {result, Operand(32u), Operand(0u)});
                 return true;
             },
             [&](const type::Vector* vec) {  //
                 return GenerateVectorType(vec, result);
             },
             [&](const type::Void*) {
-                push_type(spv::Op::OpTypeVoid, {result});
+                module_.PushType(spv::Op::OpTypeVoid, {result});
                 return true;
             },
             [&](const type::StorageTexture* tex) {
@@ -3734,7 +3673,7 @@
             },
             [&](const type::Texture* tex) { return GenerateTextureType(tex, result); },
             [&](const type::Sampler* s) {
-                push_type(spv::Op::OpTypeSampler, {result});
+                module_.PushType(spv::Op::OpTypeSampler, {result});
 
                 // Register both of the sampler type names. In SPIR-V they're the same
                 // sampler type, so we need to match that when we do the dedup check.
@@ -3776,9 +3715,9 @@
     if (dim == type::TextureDimension::k1d) {
         dim_literal = SpvDim1D;
         if (texture->Is<type::SampledTexture>()) {
-            push_capability(SpvCapabilitySampled1D);
+            module_.PushCapability(SpvCapabilitySampled1D);
         } else if (texture->Is<type::StorageTexture>()) {
-            push_capability(SpvCapabilityImage1D);
+            module_.PushCapability(SpvCapabilityImage1D);
         }
     }
     if (dim == type::TextureDimension::k3d) {
@@ -3806,7 +3745,7 @@
 
     if (dim == type::TextureDimension::kCubeArray) {
         if (texture->IsAnyOf<type::SampledTexture, type::DepthTexture>()) {
-            push_capability(SpvCapabilitySampledCubeArray);
+            module_.PushCapability(SpvCapabilitySampledCubeArray);
         }
     }
 
@@ -3831,10 +3770,10 @@
         format_literal = convert_texel_format_to_spv(t->texel_format());
     }
 
-    push_type(spv::Op::OpTypeImage,
-              {result, Operand(type_id), Operand(dim_literal), Operand(depth_literal),
-               Operand(array_literal), Operand(ms_literal), Operand(sampled_literal),
-               Operand(format_literal)});
+    module_.PushType(spv::Op::OpTypeImage,
+                     {result, Operand(type_id), Operand(dim_literal), Operand(depth_literal),
+                      Operand(array_literal), Operand(ms_literal), Operand(sampled_literal),
+                      Operand(format_literal)});
 
     return true;
 }
@@ -3847,7 +3786,7 @@
 
     auto result_id = std::get<uint32_t>(result);
     if (arr->Count()->Is<type::RuntimeArrayCount>()) {
-        push_type(spv::Op::OpTypeRuntimeArray, {result, Operand(elem_type)});
+        module_.PushType(spv::Op::OpTypeRuntimeArray, {result, Operand(elem_type)});
     } else {
         auto count = arr->ConstantCount();
         if (!count) {
@@ -3860,11 +3799,12 @@
             return false;
         }
 
-        push_type(spv::Op::OpTypeArray, {result, Operand(elem_type), Operand(len_id)});
+        module_.PushType(spv::Op::OpTypeArray, {result, Operand(elem_type), Operand(len_id)});
     }
 
-    push_annot(spv::Op::OpDecorate,
-               {Operand(result_id), U32Operand(SpvDecorationArrayStride), Operand(arr->Stride())});
+    module_.PushAnnot(
+        spv::Op::OpDecorate,
+        {Operand(result_id), U32Operand(SpvDecorationArrayStride), Operand(arr->Stride())});
     return true;
 }
 
@@ -3875,7 +3815,8 @@
         return false;
     }
 
-    push_type(spv::Op::OpTypeMatrix, {result, Operand(col_type_id), Operand(mat->columns())});
+    module_.PushType(spv::Op::OpTypeMatrix,
+                     {result, Operand(col_type_id), Operand(mat->columns())});
     return true;
 }
 
@@ -3891,7 +3832,7 @@
         return false;
     }
 
-    push_type(spv::Op::OpTypePointer, {result, U32Operand(stg_class), Operand(subtype_id)});
+    module_.PushType(spv::Op::OpTypePointer, {result, U32Operand(stg_class), Operand(subtype_id)});
 
     return true;
 }
@@ -3908,7 +3849,7 @@
         return false;
     }
 
-    push_type(spv::Op::OpTypePointer, {result, U32Operand(stg_class), Operand(subtype_id)});
+    module_.PushType(spv::Op::OpTypePointer, {result, U32Operand(stg_class), Operand(subtype_id)});
 
     return true;
 }
@@ -3917,7 +3858,8 @@
     auto struct_id = std::get<uint32_t>(result);
 
     if (struct_type->Name().IsValid()) {
-        push_debug(spv::Op::OpName, {Operand(struct_id), Operand(struct_type->Name().Name())});
+        module_.PushDebug(spv::Op::OpName,
+                          {Operand(struct_id), Operand(struct_type->Name().Name())});
     }
 
     OperandList ops;
@@ -3926,7 +3868,8 @@
     if (auto* sem_str = struct_type->As<sem::Struct>()) {
         auto* decl = sem_str->Declaration();
         if (ast::HasAttribute<transform::AddBlockAttribute::BlockAttribute>(decl->attributes)) {
-            push_annot(spv::Op::OpDecorate, {Operand(struct_id), U32Operand(SpvDecorationBlock)});
+            module_.PushAnnot(spv::Op::OpDecorate,
+                              {Operand(struct_id), U32Operand(SpvDecorationBlock)});
         }
     }
 
@@ -3939,15 +3882,15 @@
         ops.push_back(Operand(mem_id));
     }
 
-    push_type(spv::Op::OpTypeStruct, std::move(ops));
+    module_.PushType(spv::Op::OpTypeStruct, std::move(ops));
     return true;
 }
 
 uint32_t Builder::GenerateStructMember(uint32_t struct_id,
                                        uint32_t idx,
                                        const type::StructMember* member) {
-    push_debug(spv::Op::OpMemberName,
-               {Operand(struct_id), Operand(idx), Operand(member->Name().Name())});
+    module_.PushDebug(spv::Op::OpMemberName,
+                      {Operand(struct_id), Operand(idx), Operand(member->Name().Name())});
 
     // Note: This will generate layout annotations for *all* structs, whether or
     // not they are used in host-shareable variables. This is officially ok in
@@ -3955,20 +3898,20 @@
     // to only generate the layout info for structs used for certain storage
     // classes.
 
-    push_annot(spv::Op::OpMemberDecorate,
-               {Operand(struct_id), Operand(idx), U32Operand(SpvDecorationOffset),
-                Operand(member->Offset())});
+    module_.PushAnnot(spv::Op::OpMemberDecorate,
+                      {Operand(struct_id), Operand(idx), U32Operand(SpvDecorationOffset),
+                       Operand(member->Offset())});
 
     // Infer and emit matrix layout.
     auto* matrix_type = GetNestedMatrixType(member->Type());
     if (matrix_type) {
-        push_annot(spv::Op::OpMemberDecorate,
-                   {Operand(struct_id), Operand(idx), U32Operand(SpvDecorationColMajor)});
+        module_.PushAnnot(spv::Op::OpMemberDecorate,
+                          {Operand(struct_id), Operand(idx), U32Operand(SpvDecorationColMajor)});
         const uint32_t scalar_elem_size = matrix_type->type()->Size();
         const uint32_t effective_row_count = (matrix_type->rows() == 2) ? 2 : 4;
-        push_annot(spv::Op::OpMemberDecorate,
-                   {Operand(struct_id), Operand(idx), U32Operand(SpvDecorationMatrixStride),
-                    Operand(effective_row_count * scalar_elem_size)});
+        module_.PushAnnot(spv::Op::OpMemberDecorate,
+                          {Operand(struct_id), Operand(idx), U32Operand(SpvDecorationMatrixStride),
+                           Operand(effective_row_count * scalar_elem_size)});
     }
 
     return GenerateTypeIfNeeded(member->Type());
@@ -3980,7 +3923,7 @@
         return false;
     }
 
-    push_type(spv::Op::OpTypeVector, {result, Operand(type_id), Operand(vec->Width())});
+    module_.PushType(spv::Op::OpTypeVector, {result, Operand(type_id), Operand(vec->Width())});
     return true;
 }
 
@@ -4042,7 +3985,7 @@
         case builtin::BuiltinValue::kNumWorkgroups:
             return SpvBuiltInNumWorkgroups;
         case builtin::BuiltinValue::kSampleIndex:
-            push_capability(SpvCapabilitySampleRateShading);
+            module_.PushCapability(SpvCapabilitySampleRateShading);
             return SpvBuiltInSampleId;
         case builtin::BuiltinValue::kSampleMask:
             return SpvBuiltInSampleMask;
@@ -4057,10 +4000,11 @@
                                           builtin::InterpolationSampling sampling) {
     switch (type) {
         case builtin::InterpolationType::kLinear:
-            push_annot(spv::Op::OpDecorate, {Operand(id), U32Operand(SpvDecorationNoPerspective)});
+            module_.PushAnnot(spv::Op::OpDecorate,
+                              {Operand(id), U32Operand(SpvDecorationNoPerspective)});
             break;
         case builtin::InterpolationType::kFlat:
-            push_annot(spv::Op::OpDecorate, {Operand(id), U32Operand(SpvDecorationFlat)});
+            module_.PushAnnot(spv::Op::OpDecorate, {Operand(id), U32Operand(SpvDecorationFlat)});
             break;
         case builtin::InterpolationType::kPerspective:
         case builtin::InterpolationType::kUndefined:
@@ -4068,11 +4012,12 @@
     }
     switch (sampling) {
         case builtin::InterpolationSampling::kCentroid:
-            push_annot(spv::Op::OpDecorate, {Operand(id), U32Operand(SpvDecorationCentroid)});
+            module_.PushAnnot(spv::Op::OpDecorate,
+                              {Operand(id), U32Operand(SpvDecorationCentroid)});
             break;
         case builtin::InterpolationSampling::kSample:
-            push_capability(SpvCapabilitySampleRateShading);
-            push_annot(spv::Op::OpDecorate, {Operand(id), U32Operand(SpvDecorationSample)});
+            module_.PushCapability(SpvCapabilitySampleRateShading);
+            module_.PushAnnot(spv::Op::OpDecorate, {Operand(id), U32Operand(SpvDecorationSample)});
             break;
         case builtin::InterpolationSampling::kCenter:
         case builtin::InterpolationSampling::kUndefined:
@@ -4101,13 +4046,13 @@
         case builtin::TexelFormat::kRgba8Sint:
             return SpvImageFormatRgba8i;
         case builtin::TexelFormat::kRg32Uint:
-            push_capability(SpvCapabilityStorageImageExtendedFormats);
+            module_.PushCapability(SpvCapabilityStorageImageExtendedFormats);
             return SpvImageFormatRg32ui;
         case builtin::TexelFormat::kRg32Sint:
-            push_capability(SpvCapabilityStorageImageExtendedFormats);
+            module_.PushCapability(SpvCapabilityStorageImageExtendedFormats);
             return SpvImageFormatRg32i;
         case builtin::TexelFormat::kRg32Float:
-            push_capability(SpvCapabilityStorageImageExtendedFormats);
+            module_.PushCapability(SpvCapabilityStorageImageExtendedFormats);
             return SpvImageFormatRg32f;
         case builtin::TexelFormat::kRgba16Uint:
             return SpvImageFormatRgba16ui;
@@ -4128,22 +4073,22 @@
 }
 
 bool Builder::push_function_inst(spv::Op op, const OperandList& operands) {
-    if (functions_.empty()) {
+    if (!current_function_) {
         utils::StringStream ss;
         ss << "Internal error: trying to add SPIR-V instruction " << int(op)
            << " outside a function";
         error_ = ss.str();
         return false;
     }
-    functions_.back().push_inst(op, operands);
+    current_function_.push_inst(op, operands);
     return true;
 }
 
 bool Builder::InsideBasicBlock() const {
-    if (functions_.empty()) {
+    if (!current_function_) {
         return false;
     }
-    const auto& instructions = functions_.back().instructions();
+    const auto& instructions = current_function_.instructions();
     if (instructions.empty()) {
         // The Function object does not explicitly represent its entry block
         // label.  So return *true* because an empty list means the only
diff --git a/src/tint/writer/spirv/builder.h b/src/tint/writer/spirv/builder.h
index 1bbffc8..5ffa3d3 100644
--- a/src/tint/writer/spirv/builder.h
+++ b/src/tint/writer/spirv/builder.h
@@ -15,6 +15,7 @@
 #ifndef SRC_TINT_WRITER_SPIRV_BUILDER_H_
 #define SRC_TINT_WRITER_SPIRV_BUILDER_H_
 
+#include <memory>
 #include <string>
 #include <unordered_map>
 #include <unordered_set>
@@ -39,6 +40,7 @@
 #include "src/tint/sem/builtin.h"
 #include "src/tint/type/storage_texture.h"
 #include "src/tint/writer/spirv/function.h"
+#include "src/tint/writer/spirv/module.h"
 #include "src/tint/writer/spirv/scalar_constant.h"
 
 // Forward declarations
@@ -54,7 +56,7 @@
 
 namespace tint::writer::spirv {
 
-/// Builder class to create SPIR-V instructions from a module.
+/// Builder class to create a SPIR-V module from a Tint AST.
 class Builder {
   public:
     /// Contains information for generating accessor chains
@@ -92,100 +94,17 @@
     /// @returns true if the builder encountered an error
     bool has_error() const { return !error_.empty(); }
 
-    /// @returns the number of uint32_t's needed to make up the results
-    uint32_t total_size() const;
+    /// @returns the module that this builder has produced
+    spirv::Module& Module() { return module_; }
 
-    /// @returns the id bound for this program
-    uint32_t id_bound() const { return next_id_; }
-
-    /// @returns the next id to be used
-    uint32_t next_id() {
-        auto id = next_id_;
-        next_id_ += 1;
-        return id;
+    /// Add an empty function to the builder, to be used for testing purposes.
+    void PushFunctionForTesting() {
+        current_function_ = Function(Instruction(spv::Op::OpFunction, {}), {}, {});
     }
 
-    /// Iterates over all the instructions in the correct order and calls the
-    /// given callback
-    /// @param cb the callback to execute
-    void iterate(std::function<void(const Instruction&)> cb) const;
+    /// @returns the current function
+    const Function& CurrentFunction() { return current_function_; }
 
-    /// Adds an instruction to the list of capabilities, if the capability
-    /// hasn't already been added.
-    /// @param cap the capability to set
-    void push_capability(uint32_t cap);
-    /// @returns the capabilities
-    const InstructionList& capabilities() const { return capabilities_; }
-    /// Adds an instruction to the extensions
-    /// @param extension the name of the extension
-    void push_extension(const char* extension);
-    /// @returns the extensions
-    const InstructionList& extensions() const { return extensions_; }
-    /// Adds an instruction to the ext import
-    /// @param op the op to set
-    /// @param operands the operands for the instruction
-    void push_ext_import(spv::Op op, const OperandList& operands) {
-        ext_imports_.push_back(Instruction{op, operands});
-    }
-    /// @returns the ext imports
-    const InstructionList& ext_imports() const { return ext_imports_; }
-    /// Adds an instruction to the memory model
-    /// @param op the op to set
-    /// @param operands the operands for the instruction
-    void push_memory_model(spv::Op op, const OperandList& operands) {
-        memory_model_.push_back(Instruction{op, operands});
-    }
-    /// @returns the memory model
-    const InstructionList& memory_model() const { return memory_model_; }
-    /// Adds an instruction to the entry points
-    /// @param op the op to set
-    /// @param operands the operands for the instruction
-    void push_entry_point(spv::Op op, const OperandList& operands) {
-        entry_points_.push_back(Instruction{op, operands});
-    }
-    /// @returns the entry points
-    const InstructionList& entry_points() const { return entry_points_; }
-    /// Adds an instruction to the execution modes
-    /// @param op the op to set
-    /// @param operands the operands for the instruction
-    void push_execution_mode(spv::Op op, const OperandList& operands) {
-        execution_modes_.push_back(Instruction{op, operands});
-    }
-    /// @returns the execution modes
-    const InstructionList& execution_modes() const { return execution_modes_; }
-    /// Adds an instruction to the debug
-    /// @param op the op to set
-    /// @param operands the operands for the instruction
-    void push_debug(spv::Op op, const OperandList& operands) {
-        debug_.push_back(Instruction{op, operands});
-    }
-    /// @returns the debug instructions
-    const InstructionList& debug() const { return debug_; }
-    /// Adds an instruction to the types
-    /// @param op the op to set
-    /// @param operands the operands for the instruction
-    void push_type(spv::Op op, const OperandList& operands) {
-        types_.push_back(Instruction{op, operands});
-    }
-    /// @returns the type instructions
-    const InstructionList& types() const { return types_; }
-    /// Adds an instruction to the annotations
-    /// @param op the op to set
-    /// @param operands the operands for the instruction
-    void push_annot(spv::Op op, const OperandList& operands) {
-        annotations_.push_back(Instruction{op, operands});
-    }
-    /// @returns the annotations
-    const InstructionList& annots() const { return annotations_; }
-
-    /// Adds a function to the builder
-    /// @param func the function to add
-    void push_function(const Function& func) {
-        functions_.push_back(func);
-        current_label_id_ = func.label_id();
-    }
-    /// @returns the functions
-    const std::vector<Function>& functions() const { return functions_; }
     /// Pushes an instruction to the current function. If we're outside
     /// a function then issue an internal error and return false.
     /// @param op the operation
@@ -195,11 +114,11 @@
     /// Pushes a variable to the current function
     /// @param operands the variable operands
     void push_function_var(const OperandList& operands) {
-        if (TINT_UNLIKELY(functions_.empty())) {
+        if (TINT_UNLIKELY(!current_function_)) {
             TINT_ICE(Writer, builder_.Diagnostics())
                 << "push_function_var() called without a function";
         }
-        functions_.back().push_var(operands);
+        current_function_.push_var(operands);
     }
 
     /// @returns true if the current instruction insertion point is
@@ -591,18 +510,9 @@
 
     ProgramBuilder builder_;
     std::string error_;
-    uint32_t next_id_ = 1;
+    spirv::Module module_;
+    Function current_function_;
     uint32_t current_label_id_ = 0;
-    InstructionList capabilities_;
-    InstructionList extensions_;
-    InstructionList ext_imports_;
-    InstructionList memory_model_;
-    InstructionList entry_points_;
-    InstructionList execution_modes_;
-    InstructionList debug_;
-    InstructionList types_;
-    InstructionList annotations_;
-    std::vector<Function> functions_;
 
     // Scope holds per-block information
     struct Scope {
@@ -625,7 +535,6 @@
     std::vector<Scope> scope_stack_;
     std::vector<uint32_t> merge_stack_;
     std::vector<uint32_t> continue_stack_;
-    std::unordered_set<uint32_t> capability_set_;
     bool zero_initialize_workgroup_memory_ = false;
 
     struct ContinuingInfo {
diff --git a/src/tint/writer/spirv/builder_accessor_expression_test.cc b/src/tint/writer/spirv/builder_accessor_expression_test.cc
index e6692ab..6150d5a 100644
--- a/src/tint/writer/spirv/builder_accessor_expression_test.cc
+++ b/src/tint/writer/spirv/builder_accessor_expression_test.cc
@@ -34,7 +34,7 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %6 = OpTypeInt 32 1
 %5 = OpTypeVector %6 3
@@ -45,9 +45,10 @@
 %13 = OpTypePointer Function %6
 %14 = OpConstantNull %6
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%12 = OpVariable %13 Function %14
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+              R"(%12 = OpVariable %13 Function %14
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
               R"(%11 = OpCompositeExtract %6 %10 1
 OpStore %12 %11
 OpReturn
@@ -68,16 +69,17 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %5 = OpTypeInt 32 1
 %6 = OpConstant %5 2
 %8 = OpTypePointer Function %5
 %9 = OpConstantNull %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%7 = OpVariable %8 Function %9
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+              R"(%7 = OpVariable %8 Function %9
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
               R"(OpStore %7 %6
 OpReturn
 )");
@@ -97,7 +99,7 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %8 = OpTypeInt 32 0
 %7 = OpTypeVector %8 3
@@ -108,10 +110,12 @@
 %12 = OpTypePointer Function %8
 %16 = OpConstantNull %8
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %9
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+              R"(%5 = OpVariable %6 Function %9
 %15 = OpVariable %12 Function %16
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(%13 = OpAccessChain %12 %5 %11
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
+              R"(%13 = OpAccessChain %12 %5 %11
 %14 = OpLoad %8 %13
 OpStore %15 %14
 OpReturn
@@ -134,7 +138,7 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %8 = OpTypeFloat 32
 %7 = OpTypeVector %8 3
@@ -146,11 +150,12 @@
 %15 = OpTypePointer Function %8
 %19 = OpConstantNull %8
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %9
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+              R"(%5 = OpVariable %6 Function %9
 %10 = OpVariable %11 Function %13
 %18 = OpVariable %15 Function %19
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(%14 = OpLoad %12 %10
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(%14 = OpLoad %12 %10
 %16 = OpAccessChain %15 %5 %14
 %17 = OpLoad %8 %16
 OpStore %18 %17
@@ -172,7 +177,7 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %6 = OpTypeInt 32 1
 %5 = OpTypeVector %6 3
@@ -183,9 +188,10 @@
 %13 = OpTypePointer Function %6
 %14 = OpConstantNull %6
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%12 = OpVariable %13 Function %14
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+              R"(%12 = OpVariable %13 Function %14
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
               R"(%11 = OpCompositeExtract %6 %10 2
 OpStore %12 %11
 OpReturn
@@ -206,7 +212,7 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %8 = OpTypeFloat 32
 %7 = OpTypeVector %8 3
@@ -217,10 +223,12 @@
 %12 = OpTypePointer Function %8
 %16 = OpConstantNull %8
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %9
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+              R"(%5 = OpVariable %6 Function %9
 %15 = OpVariable %12 Function %16
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(%13 = OpAccessChain %12 %5 %11
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
+              R"(%13 = OpAccessChain %12 %5 %11
 %14 = OpLoad %8 %13
 OpStore %15 %14
 OpReturn
@@ -243,7 +251,7 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %8 = OpTypeFloat 32
 %7 = OpTypeVector %8 3
@@ -257,11 +265,12 @@
 %18 = OpTypePointer Function %8
 %22 = OpConstantNull %8
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %9
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+              R"(%5 = OpVariable %6 Function %9
 %12 = OpVariable %13 Function %14
 %21 = OpVariable %18 Function %22
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %12 %11
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %12 %11
 %15 = OpLoad %10 %12
 %17 = OpIAdd %10 %15 %16
 %19 = OpAccessChain %18 %5 %17
@@ -286,7 +295,7 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %7 = OpTypeFloat 32
 %6 = OpTypeVector %7 3
@@ -308,9 +317,10 @@
 %25 = OpTypePointer Function %7
 %26 = OpConstantNull %7
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%24 = OpVariable %25 Function %26
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+              R"(%24 = OpVariable %25 Function %26
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
               R"(%21 = OpCompositeExtract %6 %18 1
 %23 = OpCompositeExtract %7 %21 2
 OpStore %24 %23
@@ -333,16 +343,17 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %5 = OpTypeFloat 32
 %6 = OpConstant %5 6
 %8 = OpTypePointer Function %5
 %9 = OpConstantNull %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%7 = OpVariable %8 Function %9
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+              R"(%7 = OpVariable %8 Function %9
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
               R"(OpStore %7 %6
 OpReturn
 )");
@@ -362,7 +373,7 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %9 = OpTypeFloat 32
 %8 = OpTypeVector %9 3
@@ -377,10 +388,11 @@
 %16 = OpTypePointer Function %9
 %20 = OpConstantNull %9
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %12
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+              R"(%5 = OpVariable %6 Function %12
 %19 = OpVariable %16 Function %20
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
               R"(%17 = OpAccessChain %16 %5 %14 %15
 %18 = OpLoad %9 %17
 OpStore %19 %18
@@ -404,7 +416,7 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %9 = OpTypeFloat 32
 %8 = OpTypeVector %9 3
@@ -421,11 +433,12 @@
 %20 = OpTypePointer Function %9
 %24 = OpConstantNull %9
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %12
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+              R"(%5 = OpVariable %6 Function %12
 %15 = OpVariable %16 Function %17
 %23 = OpVariable %20 Function %24
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %15 %14
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %15 %14
 %18 = OpLoad %13 %15
 %21 = OpAccessChain %20 %5 %18 %19
 %22 = OpLoad %9 %21
@@ -449,7 +462,7 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %7 = OpTypeFloat 32
 %6 = OpTypeVector %7 3
@@ -471,9 +484,10 @@
 %25 = OpTypePointer Function %22
 %26 = OpConstantNull %22
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%24 = OpVariable %25 Function %26
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+              R"(%24 = OpVariable %25 Function %26
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
               R"(%21 = OpCompositeExtract %6 %18 1
 %23 = OpVectorShuffle %22 %21 %21 0 1
 OpStore %24 %23
@@ -495,7 +509,7 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %9 = OpTypeFloat 32
 %8 = OpTypeVector %9 3
@@ -511,10 +525,12 @@
 %21 = OpTypePointer Function %17
 %22 = OpConstantNull %17
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %12
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+              R"(%5 = OpVariable %6 Function %12
 %20 = OpVariable %21 Function %22
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(%16 = OpAccessChain %15 %5 %14
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
+              R"(%16 = OpAccessChain %15 %5 %14
 %18 = OpLoad %8 %16
 %19 = OpVectorShuffle %17 %18 %18 0 1
 OpStore %20 %19
@@ -538,7 +554,7 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %9 = OpTypeFloat 32
 %8 = OpTypeVector %9 3
@@ -556,11 +572,12 @@
 %25 = OpTypePointer Function %21
 %26 = OpConstantNull %21
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %12
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+              R"(%5 = OpVariable %6 Function %12
 %15 = OpVariable %16 Function %17
 %24 = OpVariable %25 Function %26
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %15 %14
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %15 %14
 %18 = OpLoad %13 %15
 %20 = OpAccessChain %19 %5 %18
 %22 = OpLoad %8 %20
@@ -589,7 +606,7 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %7 = OpTypeFloat 32
 %6 = OpTypeVector %7 2
@@ -607,9 +624,10 @@
 %19 = OpConstantNull %8
 %22 = OpTypePointer Function %7
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%21 = OpVariable %22 Function %10
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+              R"(%21 = OpVariable %22 Function %10
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
               R"(%18 = OpCompositeExtract %6 %16 1
 %20 = OpCompositeExtract %7 %18 0
 OpStore %21 %20
@@ -636,16 +654,17 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %5 = OpTypeFloat 32
 %6 = OpConstant %5 -0.5
 %8 = OpTypePointer Function %5
 %9 = OpConstantNull %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%7 = OpVariable %8 Function %9
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+              R"(%7 = OpVariable %8 Function %9
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
               R"(OpStore %7 %6
 OpReturn
 )");
@@ -665,7 +684,7 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %9 = OpTypeFloat 32
 %8 = OpTypeVector %9 3
@@ -679,10 +698,11 @@
 %15 = OpTypePointer Function %9
 %19 = OpConstantNull %9
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %12
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+              R"(%5 = OpVariable %6 Function %12
 %18 = OpVariable %15 Function %19
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
               R"(%16 = OpAccessChain %15 %5 %13 %14
 %17 = OpLoad %9 %16
 OpStore %18 %17
@@ -706,7 +726,7 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %9 = OpTypeFloat 32
 %10 = OpTypeInt 32 0
@@ -722,11 +742,12 @@
 %19 = OpTypePointer Function %9
 %23 = OpConstantNull %9
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %13
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+              R"(%5 = OpVariable %6 Function %13
 %15 = OpVariable %16 Function %17
 %22 = OpVariable %19 Function %23
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %15 %14
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %15 %14
 %18 = OpLoad %10 %15
 %20 = OpAccessChain %19 %5 %18 %14
 %21 = OpLoad %9 %20
@@ -751,7 +772,7 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %7 = OpTypeFloat 32
 %6 = OpTypeVector %7 2
@@ -768,9 +789,10 @@
 %19 = OpTypePointer Function %6
 %20 = OpConstantNull %6
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%18 = OpVariable %19 Function %20
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+              R"(%18 = OpVariable %19 Function %20
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
               R"(%17 = OpCompositeExtract %6 %14 1
 OpStore %18 %17
 OpReturn
@@ -793,7 +815,7 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %6 = OpTypeFloat 32
 %5 = OpTypeVector %6 2
@@ -803,9 +825,10 @@
 %11 = OpTypePointer Function %5
 %12 = OpConstantNull %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%10 = OpVariable %11 Function %12
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+              R"(%10 = OpVariable %11 Function %12
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
               R"(OpStore %10 %9
 OpReturn
 )");
@@ -825,7 +848,7 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %9 = OpTypeFloat 32
 %8 = OpTypeVector %9 2
@@ -837,10 +860,12 @@
 %13 = OpTypePointer Function %8
 %17 = OpConstantNull %8
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %10
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+              R"(%5 = OpVariable %6 Function %10
 %16 = OpVariable %13 Function %17
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(%14 = OpAccessChain %13 %5 %12
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
+              R"(%14 = OpAccessChain %13 %5 %12
 %15 = OpLoad %8 %14
 OpStore %16 %15
 OpReturn
@@ -863,7 +888,7 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %9 = OpTypeFloat 32
 %8 = OpTypeVector %9 2
@@ -876,11 +901,12 @@
 %16 = OpTypePointer Function %8
 %20 = OpConstantNull %8
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %10
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+              R"(%5 = OpVariable %6 Function %10
 %11 = OpVariable %12 Function %14
 %19 = OpVariable %16 Function %20
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(%15 = OpLoad %13 %11
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(%15 = OpLoad %13 %11
 %17 = OpAccessChain %16 %5 %15
 %18 = OpLoad %8 %17
 OpStore %19 %18
@@ -912,7 +938,7 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %8 = OpTypeFloat 32
 %7 = OpTypeStruct %8 %8
@@ -922,9 +948,11 @@
 %11 = OpConstant %10 1
 %12 = OpTypePointer Function %8
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %9
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+              R"(%5 = OpVariable %6 Function %9
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(%13 = OpAccessChain %12 %5 %11
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
+              R"(%13 = OpAccessChain %12 %5 %11
 %14 = OpLoad %8 %13
 OpReturn
 )");
@@ -958,7 +986,7 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %9 = OpTypeFloat 32
 %8 = OpTypeStruct %9 %9
@@ -970,9 +998,10 @@
 %13 = OpConstant %11 1
 %14 = OpTypePointer Function %9
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %10
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+              R"(%5 = OpVariable %6 Function %10
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
               R"(%15 = OpAccessChain %14 %5 %12 %13
 %16 = OpLoad %9 %15
 OpReturn
@@ -1003,14 +1032,15 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %6 = OpTypeFloat 32
 %5 = OpTypeStruct %6 %6
 %7 = OpConstantNull %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"()");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(%8 = OpCompositeExtract %6 %7 1
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()), R"()");
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
+              R"(%8 = OpCompositeExtract %6 %7 1
 OpReturn
 )");
 
@@ -1044,15 +1074,15 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %7 = OpTypeFloat 32
 %6 = OpTypeStruct %7 %7
 %5 = OpTypeStruct %6
 %8 = OpConstantNull %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"()");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()), R"()");
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
               R"(%9 = OpCompositeExtract %6 %8 0
 %10 = OpCompositeExtract %7 %9 1
 OpReturn
@@ -1089,7 +1119,7 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %9 = OpTypeFloat 32
 %8 = OpTypeStruct %9 %9
@@ -1100,9 +1130,10 @@
 %12 = OpConstant %11 0
 %13 = OpTypePointer Function %9
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %10
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+              R"(%5 = OpVariable %6 Function %10
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
               R"(%14 = OpAccessChain %13 %5 %12 %12
 %15 = OpLoad %9 %14
 OpReturn
@@ -1136,7 +1167,7 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %9 = OpTypeFloat 32
 %8 = OpTypeStruct %9 %9
@@ -1148,9 +1179,10 @@
 %13 = OpTypePointer Function %9
 %15 = OpConstant %9 2
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %10
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+              R"(%5 = OpVariable %6 Function %10
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
               R"(%14 = OpAccessChain %13 %5 %12 %12
 OpStore %14 %15
 OpReturn
@@ -1188,7 +1220,7 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %9 = OpTypeFloat 32
 %8 = OpTypeStruct %9 %9
@@ -1200,10 +1232,11 @@
 %14 = OpTypeInt 32 0
 %15 = OpConstant %14 0
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %10
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+              R"(%5 = OpVariable %6 Function %10
 %11 = OpVariable %12 Function %13
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
               R"(%16 = OpAccessChain %12 %5 %15 %15
 %17 = OpLoad %9 %16
 OpStore %11 %17
@@ -1225,7 +1258,7 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %8 = OpTypeFloat 32
 %7 = OpTypeVector %8 3
@@ -1235,9 +1268,11 @@
 %11 = OpConstant %10 1
 %12 = OpTypePointer Function %8
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %9
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+              R"(%5 = OpVariable %6 Function %9
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(%13 = OpAccessChain %12 %5 %11
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
+              R"(%13 = OpAccessChain %12 %5 %11
 %14 = OpLoad %8 %13
 OpReturn
 )");
@@ -1257,7 +1292,7 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %8 = OpTypeFloat 32
 %7 = OpTypeVector %8 3
@@ -1265,9 +1300,10 @@
 %9 = OpConstantNull %7
 %11 = OpTypeVector %8 2
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %9
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+              R"(%5 = OpVariable %6 Function %9
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(%10 = OpLoad %7 %5
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(%10 = OpLoad %7 %5
 %12 = OpVectorShuffle %11 %10 %10 1 0
 OpReturn
 )");
@@ -1287,7 +1323,7 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %8 = OpTypeFloat 32
 %7 = OpTypeVector %8 3
@@ -1295,9 +1331,10 @@
 %9 = OpConstantNull %7
 %12 = OpTypeVector %8 2
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %9
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+              R"(%5 = OpVariable %6 Function %9
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(%10 = OpLoad %7 %5
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(%10 = OpLoad %7 %5
 %11 = OpVectorShuffle %7 %10 %10 1 0 2
 %13 = OpVectorShuffle %12 %11 %11 0 2
 OpReturn
@@ -1318,16 +1355,17 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %8 = OpTypeFloat 32
 %7 = OpTypeVector %8 3
 %6 = OpTypePointer Function %7
 %9 = OpConstantNull %7
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %9
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+              R"(%5 = OpVariable %6 Function %9
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(%10 = OpLoad %7 %5
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(%10 = OpLoad %7 %5
 %11 = OpVectorShuffle %7 %10 %10 1 0 2
 %12 = OpCompositeExtract %8 %11 0
 OpReturn
@@ -1348,7 +1386,7 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %8 = OpTypeFloat 32
 %7 = OpTypeVector %8 3
@@ -1357,9 +1395,10 @@
 %12 = OpTypeInt 32 1
 %13 = OpConstant %12 1
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %9
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+              R"(%5 = OpVariable %6 Function %9
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(%10 = OpLoad %7 %5
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(%10 = OpLoad %7 %5
 %11 = OpVectorShuffle %7 %10 %10 1 0 2
 %14 = OpCompositeExtract %8 %11 1
 OpReturn
@@ -1401,7 +1440,7 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %13 = OpTypeFloat 32
 %12 = OpTypeVector %13 3
@@ -1422,9 +1461,10 @@
 %22 = OpTypePointer Function %12
 %24 = OpTypeVector %13 2
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %17
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+              R"(%5 = OpVariable %6 Function %17
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
               R"(%23 = OpAccessChain %22 %5 %19 %20 %21 %20 %20
 %25 = OpLoad %12 %23
 %26 = OpVectorShuffle %24 %25 %25 1 0
diff --git a/src/tint/writer/spirv/builder_assign_test.cc b/src/tint/writer/spirv/builder_assign_test.cc
index a6b8bc9..08962ce 100644
--- a/src/tint/writer/spirv/builder_assign_test.cc
+++ b/src/tint/writer/spirv/builder_assign_test.cc
@@ -31,21 +31,21 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
     ASSERT_FALSE(b.has_error()) << b.error();
 
     EXPECT_TRUE(b.GenerateAssignStatement(assign)) << b.error();
     EXPECT_FALSE(b.has_error());
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 32
 %2 = OpTypePointer Private %3
 %4 = OpConstantNull %3
 %1 = OpVariable %2 Private %4
 %5 = OpConstant %3 1
 )");
 
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpStore %1 %5
 )");
 }
@@ -79,21 +79,21 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
     ASSERT_FALSE(b.has_error()) << b.error();
 
     EXPECT_TRUE(b.GenerateAssignStatement(assign)) << b.error();
     EXPECT_FALSE(b.has_error());
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeFloat 32
 %3 = OpTypeVector %4 3
 %2 = OpTypePointer Private %3
 %5 = OpConstantNull %3
 %1 = OpVariable %2 Private %5
 )");
 
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpStore %1 %5
 )");
 }
@@ -109,14 +109,14 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
     ASSERT_FALSE(b.has_error()) << b.error();
 
     EXPECT_TRUE(b.GenerateAssignStatement(assign)) << b.error();
     EXPECT_FALSE(b.has_error());
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeFloat 32
 %3 = OpTypeVector %4 3
 %2 = OpTypePointer Private %3
 %5 = OpConstantNull %3
@@ -126,7 +126,7 @@
 %8 = OpConstant %4 3
 %9 = OpConstantComposite %3 %6 %7 %8
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpStore %1 %9
 )");
 }
@@ -142,14 +142,14 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
     ASSERT_FALSE(b.has_error()) << b.error();
 
     EXPECT_TRUE(b.GenerateAssignStatement(assign)) << b.error();
     EXPECT_FALSE(b.has_error());
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeFloat 32
 %3 = OpTypeVector %4 3
 %2 = OpTypePointer Private %3
 %5 = OpConstantNull %3
@@ -159,7 +159,7 @@
 %8 = OpConstant %4 3
 %9 = OpConstantComposite %3 %6 %7 %8
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpStore %1 %9
 )");
 }
@@ -185,14 +185,14 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateFunctionVariable(v)) << b.error();
     ASSERT_FALSE(b.has_error()) << b.error();
 
     EXPECT_TRUE(b.GenerateAssignStatement(assign)) << b.error();
     EXPECT_FALSE(b.has_error());
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeFloat 32
 %3 = OpTypeStruct %4 %4
 %2 = OpTypePointer Function %3
 %5 = OpConstantNull %3
@@ -202,7 +202,7 @@
 %10 = OpConstant %4 4
 )");
 
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(%9 = OpAccessChain %8 %1 %7
 OpStore %9 %10
 )");
@@ -218,14 +218,14 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
     ASSERT_FALSE(b.has_error()) << b.error();
 
     EXPECT_TRUE(b.GenerateAssignStatement(assign)) << b.error();
     EXPECT_FALSE(b.has_error());
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeFloat 32
 %3 = OpTypeVector %4 3
 %2 = OpTypePointer Private %3
 %5 = OpConstantNull %3
@@ -235,7 +235,7 @@
 %8 = OpConstantComposite %3 %6 %6 %7
 )");
 
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpStore %1 %8
 )");
 }
@@ -251,14 +251,14 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
     ASSERT_FALSE(b.has_error()) << b.error();
 
     EXPECT_TRUE(b.GenerateAssignStatement(assign)) << b.error();
     EXPECT_FALSE(b.has_error());
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeFloat 32
 %3 = OpTypeVector %4 3
 %2 = OpTypePointer Private %3
 %5 = OpConstantNull %3
@@ -269,7 +269,7 @@
 %10 = OpConstant %4 1
 )");
 
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(%9 = OpAccessChain %8 %1 %7
 OpStore %9 %10
 )");
@@ -286,14 +286,14 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
     ASSERT_FALSE(b.has_error()) << b.error();
 
     EXPECT_TRUE(b.GenerateAssignStatement(assign)) << b.error();
     EXPECT_FALSE(b.has_error());
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeFloat 32
 %3 = OpTypeVector %4 3
 %2 = OpTypePointer Private %3
 %5 = OpConstantNull %3
@@ -304,7 +304,7 @@
 %10 = OpConstant %4 1
 )");
 
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(%9 = OpAccessChain %8 %1 %7
 OpStore %9 %10
 )");
diff --git a/src/tint/writer/spirv/builder_binary_expression_test.cc b/src/tint/writer/spirv/builder_binary_expression_test.cc
index 705bf77..ed4dc59 100644
--- a/src/tint/writer/spirv/builder_binary_expression_test.cc
+++ b/src/tint/writer/spirv/builder_binary_expression_test.cc
@@ -46,14 +46,14 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
 
     EXPECT_EQ(b.GenerateBinaryExpression(expr), 4u) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 1
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeInt 32 1
 %2 = OpConstant %1 3
 %3 = OpConstant %1 4
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               "%4 = " + param.name + " %1 %2 %3\n");
 }
 
@@ -75,15 +75,15 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
 
     EXPECT_EQ(b.GenerateBinaryExpression(expr), 5u) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 1
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeInt 32 1
 %1 = OpTypeVector %2 3
 %3 = OpConstant %2 1
 %4 = OpConstantComposite %1 %3 %3 %3
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               "%5 = " + param.name + " %1 %4 %4\n");
 }
 TEST_P(BinaryArithSignedIntegerTest, Scalar_Loads) {
@@ -96,19 +96,19 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
     EXPECT_EQ(b.GenerateBinaryExpression(expr), 7u) << b.error();
     ASSERT_FALSE(b.has_error()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeInt 32 1
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeInt 32 1
 %2 = OpTypePointer Function %3
 %4 = OpConstantNull %3
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().variables()),
               R"(%1 = OpVariable %2 Function %4
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(%5 = OpLoad %3 %1
 %6 = OpLoad %3 %1
 %7 = )" + param.name +
@@ -140,14 +140,14 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
 
     EXPECT_EQ(b.GenerateBinaryExpression(expr), 4u) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 0
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeInt 32 0
 %2 = OpConstant %1 3
 %3 = OpConstant %1 4
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               "%4 = " + param.name + " %1 %2 %3\n");
 }
 TEST_P(BinaryArithUnsignedIntegerTest, Vector) {
@@ -168,15 +168,15 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
 
     EXPECT_EQ(b.GenerateBinaryExpression(expr), 5u) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 0
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeInt 32 0
 %1 = OpTypeVector %2 3
 %3 = OpConstant %2 1
 %4 = OpConstantComposite %1 %3 %3 %3
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               "%5 = " + param.name + " %1 %4 %4\n");
 }
 INSTANTIATE_TEST_SUITE_P(
@@ -206,14 +206,14 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
 
     EXPECT_EQ(b.GenerateBinaryExpression(expr), 4u) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 32
 %2 = OpConstant %1 3.20000005
 %3 = OpConstant %1 4.5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               "%4 = " + param.name + " %1 %2 %3\n");
 }
 
@@ -229,15 +229,15 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
 
     EXPECT_EQ(b.GenerateBinaryExpression(expr), 5u) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeVector %2 3
 %3 = OpConstant %2 1
 %4 = OpConstantComposite %1 %3 %3 %3
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               "%5 = " + param.name + " %1 %4 %4\n");
 }
 INSTANTIATE_TEST_SUITE_P(BuilderTest,
@@ -263,14 +263,14 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
 
     EXPECT_EQ(b.GenerateBinaryExpression(expr), 4u) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 16
 %2 = OpConstant %1 0x1.998p+1
 %3 = OpConstant %1 0x1.2p+2
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               "%4 = " + param.name + " %1 %2 %3\n");
 }
 
@@ -288,15 +288,15 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
 
     EXPECT_EQ(b.GenerateBinaryExpression(expr), 5u) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
 %1 = OpTypeVector %2 3
 %3 = OpConstant %2 0x1p+0
 %4 = OpConstantComposite %1 %3 %3 %3
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               "%5 = " + param.name + " %1 %4 %4\n");
 }
 INSTANTIATE_TEST_SUITE_P(BuilderTest,
@@ -320,14 +320,14 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
 
     EXPECT_EQ(b.GenerateBinaryExpression(expr), 4u) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeBool
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeBool
 %2 = OpConstantTrue %1
 %3 = OpConstantNull %1
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               "%4 = " + param.name + " %1 %2 %3\n");
 }
 
@@ -343,17 +343,17 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
 
     EXPECT_EQ(b.GenerateBinaryExpression(expr), 7u) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeBool
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeBool
 %1 = OpTypeVector %2 3
 %3 = OpConstantNull %2
 %4 = OpConstantTrue %2
 %5 = OpConstantComposite %1 %3 %4 %3
 %6 = OpConstantComposite %1 %4 %3 %4
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               "%7 = " + param.name + " %1 %5 %6\n");
 }
 INSTANTIATE_TEST_SUITE_P(BuilderTest,
@@ -376,15 +376,15 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
 
     EXPECT_EQ(b.GenerateBinaryExpression(expr), 4u) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 0
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeInt 32 0
 %2 = OpConstant %1 3
 %3 = OpConstant %1 4
 %5 = OpTypeBool
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               "%4 = " + param.name + " %5 %2 %3\n");
 }
 
@@ -400,17 +400,17 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
 
     EXPECT_EQ(b.GenerateBinaryExpression(expr), 5u) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 0
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeInt 32 0
 %1 = OpTypeVector %2 3
 %3 = OpConstant %2 1
 %4 = OpConstantComposite %1 %3 %3 %3
 %7 = OpTypeBool
 %6 = OpTypeVector %7 3
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               "%5 = " + param.name + " %6 %4 %4\n");
 }
 INSTANTIATE_TEST_SUITE_P(
@@ -436,15 +436,15 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
 
     EXPECT_EQ(b.GenerateBinaryExpression(expr), 4u) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 1
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeInt 32 1
 %2 = OpConstant %1 3
 %3 = OpConstant %1 4
 %5 = OpTypeBool
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               "%4 = " + param.name + " %5 %2 %3\n");
 }
 
@@ -460,17 +460,17 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
 
     EXPECT_EQ(b.GenerateBinaryExpression(expr), 5u) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 1
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeInt 32 1
 %1 = OpTypeVector %2 3
 %3 = OpConstant %2 1
 %4 = OpConstantComposite %1 %3 %3 %3
 %7 = OpTypeBool
 %6 = OpTypeVector %7 3
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               "%5 = " + param.name + " %6 %4 %4\n");
 }
 INSTANTIATE_TEST_SUITE_P(
@@ -496,15 +496,15 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
 
     EXPECT_EQ(b.GenerateBinaryExpression(expr), 4u) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 32
 %2 = OpConstant %1 3.20000005
 %3 = OpConstant %1 4.5
 %5 = OpTypeBool
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               "%4 = " + param.name + " %5 %2 %3\n");
 }
 
@@ -520,17 +520,17 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
 
     EXPECT_EQ(b.GenerateBinaryExpression(expr), 5u) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeVector %2 3
 %3 = OpConstant %2 1
 %4 = OpConstantComposite %1 %3 %3 %3
 %7 = OpTypeBool
 %6 = OpTypeVector %7 3
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               "%5 = " + param.name + " %6 %4 %4\n");
 }
 INSTANTIATE_TEST_SUITE_P(
@@ -558,15 +558,15 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
 
     EXPECT_EQ(b.GenerateBinaryExpression(expr), 4u) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 16
 %2 = OpConstant %1 0x1.998p+1
 %3 = OpConstant %1 0x1.2p+2
 %5 = OpTypeBool
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               "%4 = " + param.name + " %5 %2 %3\n");
 }
 
@@ -584,17 +584,17 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
 
     EXPECT_EQ(b.GenerateBinaryExpression(expr), 5u) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
 %1 = OpTypeVector %2 3
 %3 = OpConstant %2 0x1p+0
 %4 = OpConstantComposite %1 %3 %3 %3
 %7 = OpTypeBool
 %6 = OpTypeVector %7 3
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               "%5 = " + param.name + " %6 %4 %4\n");
 }
 INSTANTIATE_TEST_SUITE_P(
@@ -617,16 +617,16 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
 
     EXPECT_EQ(b.GenerateBinaryExpression(expr), 5u) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()),
+    EXPECT_EQ(DumpInstructions(b.Module().Types()),
               R"(%2 = OpTypeFloat 32
 %1 = OpTypeVector %2 3
 %3 = OpConstant %2 1
 %4 = OpConstantComposite %1 %3 %3 %3
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               "%5 = OpVectorTimesScalar %1 %4 %3\n");
 }
 
@@ -642,16 +642,16 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
 
     EXPECT_EQ(b.GenerateBinaryExpression(expr), 5u) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()),
+    EXPECT_EQ(DumpInstructions(b.Module().Types()),
               R"(%2 = OpTypeFloat 16
 %1 = OpTypeVector %2 3
 %3 = OpConstant %2 0x1p+0
 %4 = OpConstantComposite %1 %3 %3 %3
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               "%5 = OpVectorTimesScalar %1 %4 %3\n");
 }
 
@@ -665,16 +665,16 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
 
     EXPECT_EQ(b.GenerateBinaryExpression(expr), 5u) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()),
+    EXPECT_EQ(DumpInstructions(b.Module().Types()),
               R"(%1 = OpTypeFloat 32
 %2 = OpConstant %1 1
 %3 = OpTypeVector %1 3
 %4 = OpConstantComposite %3 %2 %2 %2
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               "%5 = OpVectorTimesScalar %3 %4 %2\n");
 }
 
@@ -690,16 +690,16 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
 
     EXPECT_EQ(b.GenerateBinaryExpression(expr), 5u) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()),
+    EXPECT_EQ(DumpInstructions(b.Module().Types()),
               R"(%1 = OpTypeFloat 16
 %2 = OpConstant %1 0x1p+0
 %3 = OpTypeVector %1 3
 %4 = OpConstantComposite %3 %2 %2 %2
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               "%5 = OpVectorTimesScalar %3 %4 %2\n");
 }
 
@@ -711,11 +711,11 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
 
     EXPECT_EQ(b.GenerateBinaryExpression(expr), 9u) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()),
+    EXPECT_EQ(DumpInstructions(b.Module().Types()),
               R"(%5 = OpTypeFloat 32
 %4 = OpTypeVector %5 3
 %3 = OpTypeMatrix %4 3
@@ -723,7 +723,7 @@
 %6 = OpConstantNull %3
 %8 = OpConstant %5 1
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(%7 = OpLoad %3 %1
 %9 = OpMatrixTimesScalar %3 %7 %8
 )");
@@ -739,11 +739,11 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
 
     EXPECT_EQ(b.GenerateBinaryExpression(expr), 9u) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()),
+    EXPECT_EQ(DumpInstructions(b.Module().Types()),
               R"(%5 = OpTypeFloat 16
 %4 = OpTypeVector %5 3
 %3 = OpTypeMatrix %4 3
@@ -751,7 +751,7 @@
 %6 = OpConstantNull %3
 %8 = OpConstant %5 0x1p+0
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(%7 = OpLoad %3 %1
 %9 = OpMatrixTimesScalar %3 %7 %8
 )");
@@ -765,11 +765,11 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
 
     EXPECT_EQ(b.GenerateBinaryExpression(expr), 9u) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()),
+    EXPECT_EQ(DumpInstructions(b.Module().Types()),
               R"(%5 = OpTypeFloat 32
 %4 = OpTypeVector %5 3
 %3 = OpTypeMatrix %4 3
@@ -777,7 +777,7 @@
 %6 = OpConstantNull %3
 %7 = OpConstant %5 1
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(%8 = OpLoad %3 %1
 %9 = OpMatrixTimesScalar %3 %8 %7
 )");
@@ -793,11 +793,11 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
 
     EXPECT_EQ(b.GenerateBinaryExpression(expr), 9u) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()),
+    EXPECT_EQ(DumpInstructions(b.Module().Types()),
               R"(%5 = OpTypeFloat 16
 %4 = OpTypeVector %5 3
 %3 = OpTypeMatrix %4 3
@@ -805,7 +805,7 @@
 %6 = OpConstantNull %3
 %7 = OpConstant %5 0x1p+0
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(%8 = OpLoad %3 %1
 %9 = OpMatrixTimesScalar %3 %8 %7
 )");
@@ -820,11 +820,11 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
 
     EXPECT_EQ(b.GenerateBinaryExpression(expr), 10u) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()),
+    EXPECT_EQ(DumpInstructions(b.Module().Types()),
               R"(%5 = OpTypeFloat 32
 %4 = OpTypeVector %5 3
 %3 = OpTypeMatrix %4 3
@@ -833,7 +833,7 @@
 %8 = OpConstant %5 1
 %9 = OpConstantComposite %4 %8 %8 %8
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(%7 = OpLoad %3 %1
 %10 = OpMatrixTimesVector %4 %7 %9
 )");
@@ -850,11 +850,11 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
 
     EXPECT_EQ(b.GenerateBinaryExpression(expr), 10u) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()),
+    EXPECT_EQ(DumpInstructions(b.Module().Types()),
               R"(%5 = OpTypeFloat 16
 %4 = OpTypeVector %5 3
 %3 = OpTypeMatrix %4 3
@@ -863,7 +863,7 @@
 %8 = OpConstant %5 0x1p+0
 %9 = OpConstantComposite %4 %8 %8 %8
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(%7 = OpLoad %3 %1
 %10 = OpMatrixTimesVector %4 %7 %9
 )");
@@ -878,11 +878,11 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
 
     EXPECT_EQ(b.GenerateBinaryExpression(expr), 10u) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()),
+    EXPECT_EQ(DumpInstructions(b.Module().Types()),
               R"(%5 = OpTypeFloat 32
 %4 = OpTypeVector %5 3
 %3 = OpTypeMatrix %4 3
@@ -891,7 +891,7 @@
 %7 = OpConstant %5 1
 %8 = OpConstantComposite %4 %7 %7 %7
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(%9 = OpLoad %3 %1
 %10 = OpVectorTimesMatrix %4 %8 %9
 )");
@@ -909,11 +909,11 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
 
     EXPECT_EQ(b.GenerateBinaryExpression(expr), 10u) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()),
+    EXPECT_EQ(DumpInstructions(b.Module().Types()),
               R"(%5 = OpTypeFloat 16
 %4 = OpTypeVector %5 3
 %3 = OpTypeMatrix %4 3
@@ -922,7 +922,7 @@
 %7 = OpConstant %5 0x1p+0
 %8 = OpConstantComposite %4 %7 %7 %7
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(%9 = OpLoad %3 %1
 %10 = OpVectorTimesMatrix %4 %8 %9
 )");
@@ -936,18 +936,18 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
 
     EXPECT_EQ(b.GenerateBinaryExpression(expr), 9u) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()),
+    EXPECT_EQ(DumpInstructions(b.Module().Types()),
               R"(%5 = OpTypeFloat 32
 %4 = OpTypeVector %5 3
 %3 = OpTypeMatrix %4 3
 %2 = OpTypePointer Function %3
 %6 = OpConstantNull %3
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(%7 = OpLoad %3 %1
 %8 = OpLoad %3 %1
 %9 = OpMatrixTimesMatrix %3 %7 %8
@@ -964,18 +964,18 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
 
     EXPECT_EQ(b.GenerateBinaryExpression(expr), 9u) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()),
+    EXPECT_EQ(DumpInstructions(b.Module().Types()),
               R"(%5 = OpTypeFloat 16
 %4 = OpTypeVector %5 3
 %3 = OpTypeMatrix %4 3
 %2 = OpTypePointer Function %3
 %6 = OpConstantNull %3
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(%7 = OpLoad %3 %1
 %8 = OpLoad %3 %1
 %9 = OpMatrixTimesMatrix %3 %7 %8
@@ -993,15 +993,15 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
-    b.GenerateLabel(b.next_id());
+    b.PushFunctionForTesting();
+    b.GenerateLabel(b.Module().NextId());
     ASSERT_TRUE(b.GenerateFunctionVariable(v0)) << b.error();
     ASSERT_TRUE(b.GenerateFunctionVariable(v1)) << b.error();
     ASSERT_TRUE(b.GenerateFunctionVariable(v2)) << b.error();
     ASSERT_TRUE(b.GenerateFunctionVariable(v3)) << b.error();
 
     EXPECT_EQ(b.GenerateBinaryExpression(expr), 22u) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()),
+    EXPECT_EQ(DumpInstructions(b.Module().Types()),
               R"(%2 = OpTypeInt 32 1
 %3 = OpConstant %2 1
 %5 = OpTypePointer Function %2
@@ -1011,7 +1011,7 @@
 %11 = OpConstant %2 4
 %16 = OpTypeBool
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(%1 = OpLabel
 OpStore %4 %3
 OpStore %8 %7
@@ -1041,21 +1041,21 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
-    b.GenerateLabel(b.next_id());
+    b.PushFunctionForTesting();
+    b.GenerateLabel(b.Module().NextId());
 
     ASSERT_TRUE(b.GenerateGlobalVariable(a_var)) << b.error();
     ASSERT_TRUE(b.GenerateGlobalVariable(b_var)) << b.error();
 
     EXPECT_EQ(b.GenerateBinaryExpression(expr), 12u) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeBool
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeBool
 %3 = OpConstantTrue %2
 %5 = OpTypePointer Private %2
 %4 = OpVariable %5 Private %3
 %6 = OpConstantNull %2
 %7 = OpVariable %5 Private %6
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(%1 = OpLabel
 %8 = OpLoad %2 %4
 OpSelectionMerge %9 None
@@ -1086,17 +1086,17 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     ASSERT_TRUE(b.GenerateFunctionVariable(t)) << b.error();
     ASSERT_TRUE(b.GenerateFunctionVariable(f)) << b.error();
-    b.GenerateLabel(b.next_id());
+    b.GenerateLabel(b.Module().NextId());
 
     EXPECT_EQ(b.GenerateBinaryExpression(expr), 10u) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeBool
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeBool
 %2 = OpConstantTrue %1
 %3 = OpConstantNull %1
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(%4 = OpLabel
 OpSelectionMerge %5 None
 OpBranchConditional %2 %5 %6
@@ -1131,17 +1131,17 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     ASSERT_TRUE(b.GenerateFunctionVariable(t)) << b.error();
     ASSERT_TRUE(b.GenerateFunctionVariable(f)) << b.error();
-    b.GenerateLabel(b.next_id());
+    b.GenerateLabel(b.Module().NextId());
 
     EXPECT_EQ(b.GenerateBinaryExpression(expr), 10u) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeBool
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeBool
 %2 = OpConstantTrue %1
 %3 = OpConstantNull %1
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(%4 = OpLabel
 OpSelectionMerge %5 None
 OpBranchConditional %2 %6 %5
@@ -1169,15 +1169,15 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
-    b.GenerateLabel(b.next_id());
+    b.PushFunctionForTesting();
+    b.GenerateLabel(b.Module().NextId());
     ASSERT_TRUE(b.GenerateFunctionVariable(v0)) << b.error();
     ASSERT_TRUE(b.GenerateFunctionVariable(v1)) << b.error();
     ASSERT_TRUE(b.GenerateFunctionVariable(v2)) << b.error();
     ASSERT_TRUE(b.GenerateFunctionVariable(v3)) << b.error();
 
     EXPECT_EQ(b.GenerateBinaryExpression(expr), 22u) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()),
+    EXPECT_EQ(DumpInstructions(b.Module().Types()),
               R"(%2 = OpTypeInt 32 1
 %3 = OpConstant %2 1
 %5 = OpTypePointer Function %2
@@ -1187,7 +1187,7 @@
 %11 = OpConstant %2 4
 %16 = OpTypeBool
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(%1 = OpLabel
 OpStore %4 %3
 OpStore %8 %7
@@ -1218,21 +1218,21 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
-    b.GenerateLabel(b.next_id());
+    b.PushFunctionForTesting();
+    b.GenerateLabel(b.Module().NextId());
 
     ASSERT_TRUE(b.GenerateGlobalVariable(a_var)) << b.error();
     ASSERT_TRUE(b.GenerateGlobalVariable(b_var)) << b.error();
 
     EXPECT_EQ(b.GenerateBinaryExpression(expr), 12u) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeBool
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeBool
 %3 = OpConstantTrue %2
 %5 = OpTypePointer Private %2
 %4 = OpVariable %5 Private %3
 %6 = OpConstantNull %2
 %7 = OpVariable %5 Private %6
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(%1 = OpLabel
 %8 = OpLoad %2 %4
 OpSelectionMerge %9 None
diff --git a/src/tint/writer/spirv/builder_bitcast_expression_test.cc b/src/tint/writer/spirv/builder_bitcast_expression_test.cc
index 3841e69..cc417ab 100644
--- a/src/tint/writer/spirv/builder_bitcast_expression_test.cc
+++ b/src/tint/writer/spirv/builder_bitcast_expression_test.cc
@@ -29,14 +29,14 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateBitcastExpression(bitcast), 1u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 0
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeInt 32 0
 %3 = OpTypeFloat 32
 %4 = OpConstant %3 2.4000001
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(%1 = OpBitcast %2 %4
 )");
 }
@@ -48,13 +48,13 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateBitcastExpression(bitcast), 1u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %3 = OpConstant %2 2.4000001
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(%1 = OpCopyObject %2 %3
 )");
 }
diff --git a/src/tint/writer/spirv/builder_block_test.cc b/src/tint/writer/spirv/builder_block_test.cc
index f89db11..66a9d03 100644
--- a/src/tint/writer/spirv/builder_block_test.cc
+++ b/src/tint/writer/spirv/builder_block_test.cc
@@ -32,13 +32,13 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     ASSERT_FALSE(b.has_error()) << b.error();
 
     EXPECT_TRUE(b.GenerateStatement(outer)) << b.error();
     EXPECT_FALSE(b.has_error());
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 32
 %2 = OpTypePointer Function %3
 %4 = OpConstantNull %3
 %5 = OpConstant %3 1
@@ -46,12 +46,12 @@
 %8 = OpConstant %3 3
 )");
 
-    EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().variables()),
               R"(%1 = OpVariable %2 Function %4
 %6 = OpVariable %2 Function %4
 )");
 
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpStore %1 %5
 OpStore %6 %7
 OpStore %1 %8
diff --git a/src/tint/writer/spirv/builder_builtin_test.cc b/src/tint/writer/spirv/builder_builtin_test.cc
index 280b878..5db3bff 100644
--- a/src/tint/writer/spirv/builder_builtin_test.cc
+++ b/src/tint/writer/spirv/builder_builtin_test.cc
@@ -63,7 +63,7 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
 
     ASSERT_TRUE(b.GenerateGlobalVariable(tex)) << b.error();
     ASSERT_TRUE(b.GenerateGlobalVariable(sampler)) << b.error();
@@ -71,7 +71,7 @@
     EXPECT_EQ(b.GenerateExpression(expr1), 8u) << b.error();
     EXPECT_EQ(b.GenerateExpression(expr2), 17u) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeFloat 32
 %3 = OpTypeImage %4 2D 0 0 0 1 Unknown
 %2 = OpTypePointer UniformConstant %3
 %1 = OpVariable %2 UniformConstant
@@ -85,7 +85,7 @@
 %16 = OpConstantComposite %13 %14 %15
 )");
 
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(%9 = OpLoad %7 %5
 %10 = OpLoad %3 %1
 %12 = OpSampledImage %11 %10 %9
@@ -185,7 +185,7 @@
     ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
     ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeBool
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeBool
 %2 = OpTypePointer Private %3
 %4 = OpConstantNull %3
 %1 = OpVariable %2 Private %4
@@ -194,7 +194,8 @@
 )");
 
     // both any and all are 'passthrough' for scalar booleans
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), "%10 = OpLoad %3 %1\nOpReturn\n");
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
+              "%10 = OpLoad %3 %1\nOpReturn\n");
 }
 
 TEST_P(BuiltinBoolTest, Call_Bool_Vector) {
@@ -211,7 +212,7 @@
     ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
     ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeBool
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeBool
 %3 = OpTypeVector %4 3
 %2 = OpTypePointer Private %3
 %5 = OpConstantNull %3
@@ -225,7 +226,7 @@
 OpReturn
 )",
                                       "${op}", param.op);
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), expected);
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), expected);
 }
 INSTANTIATE_TEST_SUITE_P(BuiltinBuilderTest,
                          BuiltinBoolTest,
@@ -247,7 +248,7 @@
     ASSERT_TRUE(b.GenerateGlobalVariable(bool_v3)) << b.error();
     ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeFloat 32
 %3 = OpTypeVector %4 3
 %2 = OpTypePointer Private %3
 %5 = OpConstantNull %3
@@ -260,7 +261,7 @@
 %12 = OpTypeVoid
 %11 = OpTypeFunction %12
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
               R"(%16 = OpLoad %8 %6
 %17 = OpLoad %3 %1
 %18 = OpLoad %3 %1
@@ -294,7 +295,7 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    ASSERT_EQ(b.functions().size(), 1_u);
+    ASSERT_EQ(b.Module().Functions().size(), 1_u);
 
     auto* expected_types = R"(%5 = OpTypeFloat 32
 %4 = OpTypeRuntimeArray %5
@@ -305,13 +306,13 @@
 %6 = OpTypeFunction %7
 %11 = OpTypeInt 32 0
 )";
-    auto got_types = DumpInstructions(b.types());
+    auto got_types = DumpInstructions(b.Module().Types());
     EXPECT_EQ(expected_types, got_types);
 
     auto* expected_instructions = R"(%10 = OpArrayLength %11 %1 0
 OpReturn
 )";
-    auto got_instructions = DumpInstructions(b.functions()[0].instructions());
+    auto got_instructions = DumpInstructions(b.Module().Functions()[0].instructions());
     EXPECT_EQ(expected_instructions, got_instructions);
 
     Validate(b);
@@ -338,7 +339,7 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    ASSERT_EQ(b.functions().size(), 1_u);
+    ASSERT_EQ(b.Module().Functions().size(), 1_u);
 
     auto* expected_types = R"(%4 = OpTypeFloat 32
 %5 = OpTypeRuntimeArray %4
@@ -349,13 +350,13 @@
 %6 = OpTypeFunction %7
 %11 = OpTypeInt 32 0
 )";
-    auto got_types = DumpInstructions(b.types());
+    auto got_types = DumpInstructions(b.Module().Types());
     EXPECT_EQ(expected_types, got_types);
 
     auto* expected_instructions = R"(%10 = OpArrayLength %11 %1 1
 OpReturn
 )";
-    auto got_instructions = DumpInstructions(b.functions()[0].instructions());
+    auto got_instructions = DumpInstructions(b.Module().Functions()[0].instructions());
     EXPECT_EQ(expected_instructions, got_instructions);
 
     Validate(b);
@@ -386,7 +387,7 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    ASSERT_EQ(b.functions().size(), 1_u);
+    ASSERT_EQ(b.Module().Functions().size(), 1_u);
 
     auto* expected_types = R"(%5 = OpTypeFloat 32
 %4 = OpTypeRuntimeArray %5
@@ -397,13 +398,13 @@
 %6 = OpTypeFunction %7
 %11 = OpTypeInt 32 0
 )";
-    auto got_types = DumpInstructions(b.types());
+    auto got_types = DumpInstructions(b.Module().Types());
     EXPECT_EQ(expected_types, got_types);
 
     auto* expected_instructions = R"(%10 = OpArrayLength %11 %1 0
 OpReturn
 )";
-    auto got_instructions = DumpInstructions(b.functions()[0].instructions());
+    auto got_instructions = DumpInstructions(b.Module().Functions()[0].instructions());
     EXPECT_EQ(expected_instructions, got_instructions);
 
     Validate(b);
@@ -447,7 +448,7 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    ASSERT_EQ(b.functions().size(), 1_u);
+    ASSERT_EQ(b.Module().Functions().size(), 1_u);
 
     auto* expected_types = R"(%5 = OpTypeFloat 32
 %4 = OpTypeRuntimeArray %5
@@ -458,13 +459,13 @@
 %6 = OpTypeFunction %7
 %11 = OpTypeInt 32 0
 )";
-    auto got_types = DumpInstructions(b.types());
+    auto got_types = DumpInstructions(b.Module().Types());
     EXPECT_EQ(expected_types, got_types);
 
     auto* expected_instructions = R"(%10 = OpArrayLength %11 %1 0
 OpReturn
 )";
-    auto got_instructions = DumpInstructions(b.functions()[0].instructions());
+    auto got_instructions = DumpInstructions(b.Module().Functions()[0].instructions());
     EXPECT_EQ(expected_instructions, got_instructions);
 
     Validate(b);
@@ -2166,7 +2167,7 @@
     ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
     ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeInt 32 1
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeInt 32 1
 %2 = OpTypePointer Private %3
 %4 = OpConstantNull %3
 %1 = OpVariable %2 Private %4
@@ -2179,7 +2180,7 @@
 OpReturn
 )",
                                       "${op}", param.op);
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), expected);
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), expected);
 }
 
 TEST_P(BuiltinIntTest, Call_SInt_Vector) {
@@ -2196,7 +2197,7 @@
     ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
     ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeInt 32 1
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeInt 32 1
 %3 = OpTypeVector %4 3
 %2 = OpTypePointer Private %3
 %5 = OpConstantNull %3
@@ -2210,7 +2211,7 @@
 OpReturn
 )",
                                       "${op}", param.op);
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), expected);
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), expected);
 }
 
 TEST_P(BuiltinIntTest, Call_UInt_Scalar) {
@@ -2227,7 +2228,7 @@
     ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
     ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeInt 32 0
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeInt 32 0
 %2 = OpTypePointer Private %3
 %4 = OpConstantNull %3
 %1 = OpVariable %2 Private %4
@@ -2240,7 +2241,7 @@
 OpReturn
 )",
                                       "${op}", param.op);
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), expected);
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), expected);
 }
 
 TEST_P(BuiltinIntTest, Call_UInt_Vector) {
@@ -2257,7 +2258,7 @@
     ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
     ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeInt 32 0
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeInt 32 0
 %3 = OpTypeVector %4 3
 %2 = OpTypePointer Private %3
 %5 = OpConstantNull %3
@@ -2271,7 +2272,7 @@
 OpReturn
 )",
                                       "${op}", param.op);
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), expected);
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), expected);
 }
 INSTANTIATE_TEST_SUITE_P(BuiltinBuilderTest,
                          BuiltinIntTest,
@@ -3279,7 +3280,7 @@
     ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
     ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeFloat 32
 %3 = OpTypeVector %4 3
 %2 = OpTypePointer Private %3
 %5 = OpConstantNull %3
@@ -3287,7 +3288,7 @@
 %7 = OpTypeVoid
 %6 = OpTypeFunction %7
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
               R"(%11 = OpLoad %3 %1
 %12 = OpLoad %3 %1
 %10 = OpDot %4 %11 %12
@@ -3310,7 +3311,7 @@
     ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
     ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeFloat 16
 %3 = OpTypeVector %4 3
 %2 = OpTypePointer Private %3
 %5 = OpConstantNull %3
@@ -3318,7 +3319,7 @@
 %7 = OpTypeVoid
 %6 = OpTypeFunction %7
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
               R"(%11 = OpLoad %3 %1
 %12 = OpLoad %3 %1
 %10 = OpDot %4 %11 %12
@@ -3339,7 +3340,7 @@
     ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
     ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeInt 32 0
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeInt 32 0
 %3 = OpTypeVector %4 3
 %2 = OpTypePointer Private %3
 %5 = OpConstantNull %3
@@ -3347,7 +3348,7 @@
 %7 = OpTypeVoid
 %6 = OpTypeFunction %7
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
               R"(%11 = OpLoad %3 %1
 %12 = OpLoad %3 %1
 %13 = OpCompositeExtract %4 %11 0
@@ -3378,7 +3379,7 @@
     ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
     ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeInt 32 1
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeInt 32 1
 %3 = OpTypeVector %4 3
 %2 = OpTypePointer Private %3
 %5 = OpConstantNull %3
@@ -3386,7 +3387,7 @@
 %7 = OpTypeVoid
 %6 = OpTypeFunction %7
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
               R"(%11 = OpLoad %3 %1
 %12 = OpLoad %3 %1
 %13 = OpCompositeExtract %4 %11 0
@@ -3427,7 +3428,7 @@
     ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
     ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 32
 %2 = OpTypePointer Private %3
 %4 = OpConstantNull %3
 %1 = OpVariable %2 Private %4
@@ -3440,7 +3441,7 @@
 OpReturn
 )",
                                       "${op}", param.op);
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), expected);
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), expected);
 }
 
 TEST_P(BuiltinDeriveTest, Call_Derivative_Vector) {
@@ -3461,12 +3462,12 @@
     ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
 
     if (param.name != "dpdx" && param.name != "dpdy" && param.name != "fwidth") {
-        EXPECT_EQ(DumpInstructions(b.capabilities()),
+        EXPECT_EQ(DumpInstructions(b.Module().Capabilities()),
                   R"(OpCapability DerivativeControl
 )");
     }
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeFloat 32
 %3 = OpTypeVector %4 3
 %2 = OpTypePointer Private %3
 %5 = OpConstantNull %3
@@ -3480,7 +3481,7 @@
 OpReturn
 )",
                                       "${op}", param.op);
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), expected);
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), expected);
 }
 INSTANTIATE_TEST_SUITE_P(BuiltinBuilderTest,
                          BuiltinDeriveTest,
@@ -3531,7 +3532,7 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    ASSERT_EQ(b.functions().size(), 1_u);
+    ASSERT_EQ(b.Module().Functions().size(), 1_u);
 
     auto* expected_types = R"(%5 = OpTypeInt 32 0
 %6 = OpTypeInt 32 1
@@ -3546,7 +3547,7 @@
 %15 = OpTypePointer StorageBuffer %5
 %19 = OpTypePointer StorageBuffer %6
 )";
-    auto got_types = DumpInstructions(b.types());
+    auto got_types = DumpInstructions(b.Module().Types());
     EXPECT_EQ(expected_types, got_types);
 
     auto* expected_instructions = R"(%16 = OpAccessChain %15 %1 %13 %13
@@ -3555,7 +3556,7 @@
 %17 = OpAtomicLoad %6 %20 %12 %13
 OpReturn
 )";
-    auto got_instructions = DumpInstructions(b.functions()[0].instructions());
+    auto got_instructions = DumpInstructions(b.Module().Functions()[0].instructions());
     EXPECT_EQ(expected_instructions, got_instructions);
 
     Validate(b);
@@ -3597,7 +3598,7 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    ASSERT_EQ(b.functions().size(), 1_u);
+    ASSERT_EQ(b.Module().Functions().size(), 1_u);
 
     auto* expected_types = R"(%5 = OpTypeInt 32 0
 %6 = OpTypeInt 32 1
@@ -3617,7 +3618,7 @@
 %22 = OpTypePointer StorageBuffer %5
 %27 = OpTypePointer StorageBuffer %6
 )";
-    auto got_types = DumpInstructions(b.types());
+    auto got_types = DumpInstructions(b.Module().Types());
     EXPECT_EQ(expected_types, got_types);
 
     auto* expected_instructions = R"(OpStore %12 %11
@@ -3630,7 +3631,7 @@
 OpAtomicStore %28 %11 %20 %29
 OpReturn
 )";
-    auto got_instructions = DumpInstructions(b.functions()[0].instructions());
+    auto got_instructions = DumpInstructions(b.Module().Functions()[0].instructions());
     EXPECT_EQ(expected_instructions, got_instructions);
 
     Validate(b);
@@ -3668,7 +3669,7 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    ASSERT_EQ(b.functions().size(), 1_u);
+    ASSERT_EQ(b.Module().Functions().size(), 1_u);
 
     std::string expected_types = R"(%5 = OpTypeInt 32 1
 %4 = OpTypeStruct %5
@@ -3685,7 +3686,7 @@
 %17 = OpConstant %15 0
 %19 = OpTypePointer StorageBuffer %5
 )";
-    auto got_types = DumpInstructions(b.types());
+    auto got_types = DumpInstructions(b.Module().Types());
     EXPECT_EQ(expected_types, got_types);
 
     std::string expected_instructions = R"(OpStore %11 %10
@@ -3695,7 +3696,7 @@
     expected_instructions += "%14 = " + GetParam().op + " %5 %20 %16 %17 %21\n";
     expected_instructions += "OpReturn\n";
 
-    auto got_instructions = DumpInstructions(b.functions()[0].instructions());
+    auto got_instructions = DumpInstructions(b.Module().Functions()[0].instructions());
     EXPECT_EQ(expected_instructions, got_instructions);
 
     Validate(b);
@@ -3741,7 +3742,7 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    ASSERT_EQ(b.functions().size(), 1_u);
+    ASSERT_EQ(b.Module().Functions().size(), 1_u);
 
     std::string expected_types = R"(%5 = OpTypeInt 32 0
 %4 = OpTypeStruct %5
@@ -3757,7 +3758,7 @@
 %16 = OpConstant %5 0
 %18 = OpTypePointer StorageBuffer %5
 )";
-    auto got_types = DumpInstructions(b.types());
+    auto got_types = DumpInstructions(b.Module().Types());
     EXPECT_EQ(expected_types, got_types);
 
     std::string expected_instructions = R"(OpStore %11 %10
@@ -3767,7 +3768,7 @@
     expected_instructions += "%14 = " + GetParam().op + " %5 %19 %15 %16 %20\n";
     expected_instructions += "OpReturn\n";
 
-    auto got_instructions = DumpInstructions(b.functions()[0].instructions());
+    auto got_instructions = DumpInstructions(b.Module().Functions()[0].instructions());
     EXPECT_EQ(expected_instructions, got_instructions);
 
     Validate(b);
@@ -3819,7 +3820,7 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    ASSERT_EQ(b.functions().size(), 1_u);
+    ASSERT_EQ(b.Module().Functions().size(), 1_u);
 
     auto* expected_types = R"(%5 = OpTypeInt 32 0
 %6 = OpTypeInt 32 1
@@ -3840,7 +3841,7 @@
 %23 = OpTypePointer StorageBuffer %5
 %28 = OpTypePointer StorageBuffer %6
 )";
-    auto got_types = DumpInstructions(b.types());
+    auto got_types = DumpInstructions(b.Module().Types());
     EXPECT_EQ(expected_types, got_types);
 
     auto* expected_instructions = R"(OpStore %12 %11
@@ -3853,7 +3854,7 @@
 %26 = OpAtomicExchange %6 %29 %20 %21 %30
 OpReturn
 )";
-    auto got_instructions = DumpInstructions(b.functions()[0].instructions());
+    auto got_instructions = DumpInstructions(b.Module().Functions()[0].instructions());
     EXPECT_EQ(expected_instructions, got_instructions);
 
     Validate(b);
@@ -3893,7 +3894,7 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    ASSERT_EQ(b.functions().size(), 1_u);
+    ASSERT_EQ(b.Module().Functions().size(), 1_u);
 
     auto* expected_types = R"(%5 = OpTypeInt 32 0
 %6 = OpTypeInt 32 1
@@ -3915,7 +3916,7 @@
 %28 = OpConstant %6 20
 %29 = OpConstant %6 10
 )";
-    auto got_types = DumpInstructions(b.types());
+    auto got_types = DumpInstructions(b.Module().Types());
     EXPECT_EQ(expected_types, got_types);
 
     auto* expected_instructions = R"(%18 = OpAccessChain %17 %1 %15 %15
@@ -3928,7 +3929,7 @@
 %23 = OpCompositeConstruct %24 %30 %31
 OpReturn
 )";
-    auto got_instructions = DumpInstructions(b.functions()[0].instructions());
+    auto got_instructions = DumpInstructions(b.Module().Functions()[0].instructions());
     EXPECT_EQ(expected_instructions, got_instructions);
 
     Validate(b);
@@ -4094,7 +4095,7 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    ASSERT_EQ(b.functions().size(), 1_u);
+    ASSERT_EQ(b.Module().Functions().size(), 1_u);
 
     auto* expected_types = R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
@@ -4102,13 +4103,13 @@
 %7 = OpConstant %6 2
 %8 = OpConstant %6 264
 )";
-    auto got_types = DumpInstructions(b.types());
+    auto got_types = DumpInstructions(b.Module().Types());
     EXPECT_EQ(expected_types, got_types);
 
     auto* expected_instructions = R"(OpControlBarrier %7 %7 %8
 OpReturn
 )";
-    auto got_instructions = DumpInstructions(b.functions()[0].instructions());
+    auto got_instructions = DumpInstructions(b.Module().Functions()[0].instructions());
     EXPECT_EQ(expected_instructions, got_instructions);
 
     Validate(b);
@@ -4128,7 +4129,7 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    ASSERT_EQ(b.functions().size(), 1_u);
+    ASSERT_EQ(b.Module().Functions().size(), 1_u);
 
     auto* expected_types = R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
@@ -4136,13 +4137,13 @@
 %7 = OpConstant %6 2
 %8 = OpConstant %6 72
 )";
-    auto got_types = DumpInstructions(b.types());
+    auto got_types = DumpInstructions(b.Module().Types());
     EXPECT_EQ(expected_types, got_types);
 
     auto* expected_instructions = R"(OpControlBarrier %7 %7 %8
 OpReturn
 )";
-    auto got_instructions = DumpInstructions(b.functions()[0].instructions());
+    auto got_instructions = DumpInstructions(b.Module().Functions()[0].instructions());
     EXPECT_EQ(expected_instructions, got_instructions);
 
     Validate(b);
diff --git a/src/tint/writer/spirv/builder_builtin_texture_test.cc b/src/tint/writer/spirv/builder_builtin_texture_test.cc
index 4697582..6bbd866 100644
--- a/src/tint/writer/spirv/builder_builtin_texture_test.cc
+++ b/src/tint/writer/spirv/builder_builtin_texture_test.cc
@@ -3726,16 +3726,16 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     ASSERT_TRUE(b.GenerateGlobalVariable(texture)) << b.error();
     ASSERT_TRUE(b.GenerateGlobalVariable(sampler)) << b.error();
 
     EXPECT_EQ(b.GenerateExpression(call), 8u) << b.error();
 
     auto expected = expected_texture_overload(param.overload);
-    EXPECT_EQ(expected.types, "\n" + DumpInstructions(b.types()));
-    EXPECT_EQ(expected.instructions, "\n" + DumpInstructions(b.functions()[0].instructions()));
-    EXPECT_EQ(expected.capabilities, "\n" + DumpInstructions(b.capabilities()));
+    EXPECT_EQ(expected.types, "\n" + DumpInstructions(b.Module().Types()));
+    EXPECT_EQ(expected.instructions, "\n" + DumpInstructions(b.CurrentFunction().instructions()));
+    EXPECT_EQ(expected.capabilities, "\n" + DumpInstructions(b.Module().Capabilities()));
 }
 
 // Check the SPIRV generated passes validation
diff --git a/src/tint/writer/spirv/builder_const_assert_test.cc b/src/tint/writer/spirv/builder_const_assert_test.cc
index bca6deb..e6c9f98 100644
--- a/src/tint/writer/spirv/builder_const_assert_test.cc
+++ b/src/tint/writer/spirv/builder_const_assert_test.cc
@@ -30,8 +30,8 @@
     ASSERT_TRUE(b.Build()) << b.error();
 
     // const asserts are not emitted
-    EXPECT_EQ(DumpInstructions(b.types()), "");
-    EXPECT_EQ(b.functions().size(), 0u);
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), "");
+    EXPECT_EQ(b.Module().Functions().size(), 0u);
 }
 
 TEST_F(BuilderTest, FunctionConstAssert) {
@@ -42,10 +42,10 @@
     ASSERT_TRUE(b.Build()) << b.error();
 
     // const asserts are not emitted
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpReturn
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpReturn
 )");
 }
 
diff --git a/src/tint/writer/spirv/builder_constructor_expression_test.cc b/src/tint/writer/spirv/builder_constructor_expression_test.cc
index 29a47ac..d539820 100644
--- a/src/tint/writer/spirv/builder_constructor_expression_test.cc
+++ b/src/tint/writer/spirv/builder_constructor_expression_test.cc
@@ -31,7 +31,7 @@
     EXPECT_EQ(b.GenerateConstructorExpression(g, c), 2u);
     ASSERT_FALSE(b.has_error()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 32
 %2 = OpConstant %1 42.2000008
 )");
 }
@@ -45,7 +45,7 @@
     EXPECT_EQ(b.GenerateConstructorExpression(nullptr, t), 5u);
     ASSERT_FALSE(b.has_error()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeVector %2 3
 %3 = OpConstant %2 1
 %4 = OpConstant %2 3
@@ -59,17 +59,17 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
 
     EXPECT_EQ(b.GenerateExpression(t), 4u);
     ASSERT_FALSE(b.has_error()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeVector %2 2
 %3 = OpConstant %2 1
 %4 = OpConstantComposite %1 %3 %3
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
 }
 
 TEST_F(SpvBuilderConstructorTest, Type_WithAlias) {
@@ -82,13 +82,13 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 2u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 1
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeInt 32 1
 %2 = OpConstant %1 2
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
 }
 
 TEST_F(SpvBuilderConstructorTest, Type_IdentifierExpression_Param) {
@@ -99,23 +99,23 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
 
     EXPECT_EQ(b.GenerateExpression(t), 8u);
     ASSERT_FALSE(b.has_error()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 32
 %2 = OpTypePointer Function %3
 %4 = OpConstantNull %3
 %5 = OpTypeVector %3 2
 %6 = OpConstant %3 1
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().variables()),
               R"(%1 = OpVariable %2 Function %4
 )");
 
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(%7 = OpLoad %3 %1
 %8 = OpCompositeConstruct %5 %6 %7
 )");
@@ -128,11 +128,11 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
     ASSERT_EQ(b.GenerateExpression(cast), 10u) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeVector %2 3
 %3 = OpConstant %2 1
 %4 = OpConstant %2 2
@@ -143,7 +143,7 @@
 %12 = OpTypeInt 32 0
 %11 = OpTypeVector %12 3
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpStore %7 %6
 %13 = OpLoad %1 %7
 %10 = OpBitcast %11 %13
@@ -156,15 +156,15 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
 
     EXPECT_EQ(b.GenerateExpression(cast), 2u);
     ASSERT_FALSE(b.has_error()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeBool
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeBool
 %2 = OpConstantTrue %1
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
 }
 
 TEST_F(SpvBuilderConstructorTest, Type_I32_With_I32) {
@@ -173,13 +173,13 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 2u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 1
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeInt 32 1
 %2 = OpConstant %1 2
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
 }
 
 TEST_F(SpvBuilderConstructorTest, Type_U32_With_U32) {
@@ -188,13 +188,13 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 2u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 0
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeInt 32 0
 %2 = OpConstant %1 2
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
 }
 
 TEST_F(SpvBuilderConstructorTest, Type_F32_With_F32) {
@@ -203,13 +203,13 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 2u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 32
 %2 = OpConstant %1 2
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
 }
 
 TEST_F(SpvBuilderConstructorTest, Type_F16_With_F16) {
@@ -220,13 +220,13 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 2u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 16
 %2 = OpConstant %1 0x1p+1
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
 }
 
 TEST_F(SpvBuilderConstructorTest, Type_Vec2_With_Bool_Literal) {
@@ -235,15 +235,15 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 4u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeBool
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeBool
 %1 = OpTypeVector %2 2
 %3 = OpConstantTrue %2
 %4 = OpConstantComposite %1 %3 %3
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
 }
 
 TEST_F(SpvBuilderConstructorTest, Type_Vec2_With_Bool_Var) {
@@ -253,17 +253,17 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
     ASSERT_EQ(b.GenerateExpression(cast), 8u) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeBool
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeBool
 %2 = OpConstantTrue %1
 %4 = OpTypePointer Function %1
 %5 = OpConstantNull %1
 %6 = OpTypeVector %1 2
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpStore %3 %2
 %7 = OpLoad %1 %3
 %8 = OpCompositeConstruct %6 %7 %7
@@ -276,15 +276,15 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 4u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeVector %2 2
 %3 = OpConstant %2 2
 %4 = OpConstantComposite %1 %3 %3
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
 }
 
 TEST_F(SpvBuilderConstructorTest, Type_Vec2_With_F16_Literal) {
@@ -295,15 +295,15 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 4u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
 %1 = OpTypeVector %2 2
 %3 = OpConstant %2 0x1p+1
 %4 = OpConstantComposite %1 %3 %3
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
 }
 
 TEST_F(SpvBuilderConstructorTest, Type_Vec2_With_F32_F32) {
@@ -313,17 +313,17 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateStatement(var));
     EXPECT_EQ(b.GenerateExpression(cast), 9u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 32
 %2 = OpConstant %1 2
 %4 = OpTypePointer Function %1
 %5 = OpConstantNull %1
 %6 = OpTypeVector %1 2
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpStore %3 %2
 %7 = OpLoad %1 %3
 %8 = OpLoad %1 %3
@@ -340,17 +340,17 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateStatement(var));
     EXPECT_EQ(b.GenerateExpression(cast), 9u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 16
 %2 = OpConstant %1 0x1p+1
 %4 = OpTypePointer Function %1
 %5 = OpConstantNull %1
 %6 = OpTypeVector %1 2
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpStore %3 %2
 %7 = OpLoad %1 %3
 %8 = OpLoad %1 %3
@@ -364,16 +364,16 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 5u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeVector %2 2
 %3 = OpConstant %2 1
 %4 = OpConstant %2 2
 %5 = OpConstantComposite %1 %3 %4
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
 }
 
 TEST_F(SpvBuilderConstructorTest, Type_Vec2_With_F16_F16_Const) {
@@ -384,16 +384,16 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 5u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
 %1 = OpTypeVector %2 2
 %3 = OpConstant %2 0x1p+0
 %4 = OpConstant %2 0x1p+1
 %5 = OpConstantComposite %1 %3 %4
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
 }
 
 TEST_F(SpvBuilderConstructorTest, Type_Vec2_F32_With_Vec2) {
@@ -403,11 +403,11 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateStatement(var));
     EXPECT_EQ(b.GenerateExpression(cast), 10u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeVector %2 2
 %3 = OpConstant %2 1
 %4 = OpConstant %2 2
@@ -415,7 +415,7 @@
 %7 = OpTypePointer Function %1
 %8 = OpConstantNull %1
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpStore %6 %5
 %10 = OpLoad %1 %6
 )");
@@ -430,11 +430,11 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateStatement(var));
     EXPECT_EQ(b.GenerateExpression(cast), 10u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
 %1 = OpTypeVector %2 2
 %3 = OpConstant %2 0x1p+0
 %4 = OpConstant %2 0x1p+1
@@ -442,7 +442,7 @@
 %7 = OpTypePointer Function %1
 %8 = OpConstantNull %1
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpStore %6 %5
 %10 = OpLoad %1 %6
 )");
@@ -454,16 +454,16 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 5u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeVector %2 2
 %3 = OpConstant %2 1
 %4 = OpConstant %2 2
 %5 = OpConstantComposite %1 %3 %4
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
 }
 
 TEST_F(SpvBuilderConstructorTest, Type_Vec2_F16_With_Vec2_Const) {
@@ -474,16 +474,16 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 5u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
 %1 = OpTypeVector %2 2
 %3 = OpConstant %2 0x1p+0
 %4 = OpConstant %2 0x1p+1
 %5 = OpConstantComposite %1 %3 %4
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
 }
 
 TEST_F(SpvBuilderConstructorTest, Type_Vec3_With_F32) {
@@ -493,17 +493,17 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateStatement(var));
     EXPECT_EQ(b.GenerateExpression(cast), 10u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 32
 %2 = OpConstant %1 2
 %4 = OpTypePointer Function %1
 %5 = OpConstantNull %1
 %6 = OpTypeVector %1 3
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpStore %3 %2
 %7 = OpLoad %1 %3
 %8 = OpLoad %1 %3
@@ -521,17 +521,17 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateStatement(var));
     EXPECT_EQ(b.GenerateExpression(cast), 10u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 16
 %2 = OpConstant %1 0x1p+1
 %4 = OpTypePointer Function %1
 %5 = OpConstantNull %1
 %6 = OpTypeVector %1 3
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpStore %3 %2
 %7 = OpLoad %1 %3
 %8 = OpLoad %1 %3
@@ -546,17 +546,17 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 6u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeVector %2 3
 %3 = OpConstant %2 1
 %4 = OpConstant %2 2
 %5 = OpConstant %2 3
 %6 = OpConstantComposite %1 %3 %4 %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
 }
 
 TEST_F(SpvBuilderConstructorTest, Type_Vec3_With_F16_Const) {
@@ -567,17 +567,17 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 6u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
 %1 = OpTypeVector %2 3
 %3 = OpConstant %2 0x1p+0
 %4 = OpConstant %2 0x1p+1
 %5 = OpConstant %2 0x1.8p+1
 %6 = OpConstantComposite %1 %3 %4 %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
 }
 
 TEST_F(SpvBuilderConstructorTest, Type_Vec3_With_Bool) {
@@ -587,17 +587,17 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateStatement(var));
     EXPECT_EQ(b.GenerateExpression(cast), 10u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeBool
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeBool
 %2 = OpConstantTrue %1
 %4 = OpTypePointer Function %1
 %5 = OpConstantNull %1
 %6 = OpTypeVector %1 3
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpStore %3 %2
 %7 = OpLoad %1 %3
 %8 = OpLoad %1 %3
@@ -612,16 +612,16 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 5u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeBool
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeBool
 %1 = OpTypeVector %2 3
 %3 = OpConstantTrue %2
 %4 = OpConstantNull %2
 %5 = OpConstantComposite %1 %3 %4 %3
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
 }
 
 TEST_F(SpvBuilderConstructorTest, Type_Vec3_With_F32_F32_F32) {
@@ -631,17 +631,17 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateStatement(var));
     EXPECT_EQ(b.GenerateExpression(cast), 10u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 32
 %2 = OpConstant %1 2
 %4 = OpTypePointer Function %1
 %5 = OpConstantNull %1
 %6 = OpTypeVector %1 3
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpStore %3 %2
 %7 = OpLoad %1 %3
 %8 = OpLoad %1 %3
@@ -659,17 +659,17 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateStatement(var));
     EXPECT_EQ(b.GenerateExpression(cast), 10u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 16
 %2 = OpConstant %1 0x1p+1
 %4 = OpTypePointer Function %1
 %5 = OpConstantNull %1
 %6 = OpTypeVector %1 3
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpStore %3 %2
 %7 = OpLoad %1 %3
 %8 = OpLoad %1 %3
@@ -684,17 +684,17 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 6u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeVector %2 3
 %3 = OpConstant %2 1
 %4 = OpConstant %2 2
 %5 = OpConstant %2 3
 %6 = OpConstantComposite %1 %3 %4 %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
 }
 
 TEST_F(SpvBuilderConstructorTest, Type_Vec3_With_F16_F16_F16_Const) {
@@ -705,17 +705,17 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 6u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
 %1 = OpTypeVector %2 3
 %3 = OpConstant %2 0x1p+0
 %4 = OpConstant %2 0x1p+1
 %5 = OpConstant %2 0x1.8p+1
 %6 = OpConstantComposite %1 %3 %4 %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
 }
 
 TEST_F(SpvBuilderConstructorTest, Type_Vec3_With_F32_Vec2) {
@@ -725,11 +725,11 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateStatement(var));
     EXPECT_EQ(b.GenerateExpression(cast), 14u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeVector %2 2
 %3 = OpConstant %2 2
 %4 = OpConstant %2 3
@@ -739,7 +739,7 @@
 %9 = OpTypeVector %2 3
 %10 = OpConstant %2 1
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpStore %6 %5
 %11 = OpLoad %1 %6
 %12 = OpCompositeExtract %2 %11 0
@@ -757,11 +757,11 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateStatement(var));
     EXPECT_EQ(b.GenerateExpression(cast), 14u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
 %1 = OpTypeVector %2 2
 %3 = OpConstant %2 0x1p+1
 %4 = OpConstant %2 0x1.8p+1
@@ -771,7 +771,7 @@
 %9 = OpTypeVector %2 3
 %10 = OpConstant %2 0x1p+0
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpStore %6 %5
 %11 = OpLoad %1 %6
 %12 = OpCompositeExtract %2 %11 0
@@ -786,17 +786,17 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 6u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeVector %2 3
 %3 = OpConstant %2 1
 %4 = OpConstant %2 2
 %5 = OpConstant %2 3
 %6 = OpConstantComposite %1 %3 %4 %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
 }
 
 TEST_F(SpvBuilderConstructorTest, Type_Vec3_With_F16_Vec2_Const) {
@@ -807,17 +807,17 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 6u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
 %1 = OpTypeVector %2 3
 %3 = OpConstant %2 0x1p+0
 %4 = OpConstant %2 0x1p+1
 %5 = OpConstant %2 0x1.8p+1
 %6 = OpConstantComposite %1 %3 %4 %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
 }
 
 TEST_F(SpvBuilderConstructorTest, Type_Vec3_With_Vec2_F32) {
@@ -827,11 +827,11 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateStatement(var));
     EXPECT_EQ(b.GenerateExpression(cast), 14u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeVector %2 2
 %3 = OpConstant %2 1
 %4 = OpConstant %2 2
@@ -841,7 +841,7 @@
 %9 = OpTypeVector %2 3
 %13 = OpConstant %2 3
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpStore %6 %5
 %10 = OpLoad %1 %6
 %11 = OpCompositeExtract %2 %10 0
@@ -859,11 +859,11 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateStatement(var));
     EXPECT_EQ(b.GenerateExpression(cast), 14u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
 %1 = OpTypeVector %2 2
 %3 = OpConstant %2 0x1p+0
 %4 = OpConstant %2 0x1p+1
@@ -873,7 +873,7 @@
 %9 = OpTypeVector %2 3
 %13 = OpConstant %2 0x1.8p+1
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpStore %6 %5
 %10 = OpLoad %1 %6
 %11 = OpCompositeExtract %2 %10 0
@@ -888,17 +888,17 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 6u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeVector %2 3
 %3 = OpConstant %2 1
 %4 = OpConstant %2 2
 %5 = OpConstant %2 3
 %6 = OpConstantComposite %1 %3 %4 %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
 }
 
 TEST_F(SpvBuilderConstructorTest, Type_Vec3_With_Vec2_F16_Const) {
@@ -909,17 +909,17 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 6u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
 %1 = OpTypeVector %2 3
 %3 = OpConstant %2 0x1p+0
 %4 = OpConstant %2 0x1p+1
 %5 = OpConstant %2 0x1.8p+1
 %6 = OpConstantComposite %1 %3 %4 %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
 }
 
 TEST_F(SpvBuilderConstructorTest, Type_Vec3_F32_With_Vec3) {
@@ -929,11 +929,11 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateStatement(var));
     EXPECT_EQ(b.GenerateExpression(cast), 11u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeVector %2 3
 %3 = OpConstant %2 1
 %4 = OpConstant %2 2
@@ -942,7 +942,7 @@
 %8 = OpTypePointer Function %1
 %9 = OpConstantNull %1
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpStore %7 %6
 %11 = OpLoad %1 %7
 )");
@@ -957,11 +957,11 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateStatement(var));
     EXPECT_EQ(b.GenerateExpression(cast), 11u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
 %1 = OpTypeVector %2 3
 %3 = OpConstant %2 0x1p+0
 %4 = OpConstant %2 0x1p+1
@@ -970,7 +970,7 @@
 %8 = OpTypePointer Function %1
 %9 = OpConstantNull %1
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpStore %7 %6
 %11 = OpLoad %1 %7
 )");
@@ -982,17 +982,17 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 6u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeVector %2 3
 %3 = OpConstant %2 1
 %4 = OpConstant %2 2
 %5 = OpConstant %2 3
 %6 = OpConstantComposite %1 %3 %4 %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
 }
 
 TEST_F(SpvBuilderConstructorTest, Type_Vec3_F16_With_Vec3_Const) {
@@ -1003,17 +1003,17 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 6u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
 %1 = OpTypeVector %2 3
 %3 = OpConstant %2 0x1p+0
 %4 = OpConstant %2 0x1p+1
 %5 = OpConstant %2 0x1.8p+1
 %6 = OpConstantComposite %1 %3 %4 %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
 }
 
 TEST_F(SpvBuilderConstructorTest, Type_Vec4_With_Bool) {
@@ -1023,17 +1023,17 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateStatement(var));
     EXPECT_EQ(b.GenerateExpression(cast), 8u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeBool
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeBool
 %2 = OpConstantTrue %1
 %4 = OpTypePointer Function %1
 %5 = OpConstantNull %1
 %6 = OpTypeVector %1 4
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpStore %3 %2
 %7 = OpLoad %1 %3
 %8 = OpCompositeConstruct %6 %7 %7 %7 %7
@@ -1046,15 +1046,15 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 4u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeBool
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeBool
 %1 = OpTypeVector %2 4
 %3 = OpConstantTrue %2
 %4 = OpConstantComposite %1 %3 %3 %3 %3
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
 }
 
 TEST_F(SpvBuilderConstructorTest, Type_Vec4_With_F32) {
@@ -1064,17 +1064,17 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateStatement(var));
     EXPECT_EQ(b.GenerateExpression(cast), 8u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 32
 %2 = OpConstant %1 2
 %4 = OpTypePointer Function %1
 %5 = OpConstantNull %1
 %6 = OpTypeVector %1 4
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpStore %3 %2
 %7 = OpLoad %1 %3
 %8 = OpCompositeConstruct %6 %7 %7 %7 %7
@@ -1090,17 +1090,17 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateStatement(var));
     EXPECT_EQ(b.GenerateExpression(cast), 8u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 16
 %2 = OpConstant %1 0x1p+1
 %4 = OpTypePointer Function %1
 %5 = OpConstantNull %1
 %6 = OpTypeVector %1 4
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpStore %3 %2
 %7 = OpLoad %1 %3
 %8 = OpCompositeConstruct %6 %7 %7 %7 %7
@@ -1113,15 +1113,15 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 4u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeVector %2 4
 %3 = OpConstant %2 2
 %4 = OpConstantComposite %1 %3 %3 %3 %3
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
 }
 
 TEST_F(SpvBuilderConstructorTest, Type_Vec4_With_F16_Const) {
@@ -1132,15 +1132,15 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 4u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
 %1 = OpTypeVector %2 4
 %3 = OpConstant %2 0x1p+1
 %4 = OpConstantComposite %1 %3 %3 %3 %3
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
 }
 
 TEST_F(SpvBuilderConstructorTest, Type_Vec4_With_F32_F32_F32_F32) {
@@ -1150,17 +1150,17 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateStatement(var));
     EXPECT_EQ(b.GenerateExpression(cast), 11u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 32
 %2 = OpConstant %1 2
 %4 = OpTypePointer Function %1
 %5 = OpConstantNull %1
 %6 = OpTypeVector %1 4
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpStore %3 %2
 %7 = OpLoad %1 %3
 %8 = OpLoad %1 %3
@@ -1179,17 +1179,17 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateStatement(var));
     EXPECT_EQ(b.GenerateExpression(cast), 11u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 16
 %2 = OpConstant %1 0x1p+1
 %4 = OpTypePointer Function %1
 %5 = OpConstantNull %1
 %6 = OpTypeVector %1 4
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpStore %3 %2
 %7 = OpLoad %1 %3
 %8 = OpLoad %1 %3
@@ -1205,10 +1205,10 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 7u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeVector %2 4
 %3 = OpConstant %2 1
 %4 = OpConstant %2 2
@@ -1216,7 +1216,7 @@
 %6 = OpConstant %2 4
 %7 = OpConstantComposite %1 %3 %4 %5 %6
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
 }
 
 TEST_F(SpvBuilderConstructorTest, Type_Vec4_With_F16_F16_F16_F16_Const) {
@@ -1227,10 +1227,10 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 7u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
 %1 = OpTypeVector %2 4
 %3 = OpConstant %2 0x1p+0
 %4 = OpConstant %2 0x1p+1
@@ -1238,7 +1238,7 @@
 %6 = OpConstant %2 0x1p+2
 %7 = OpConstantComposite %1 %3 %4 %5 %6
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
 }
 
 TEST_F(SpvBuilderConstructorTest, Type_Vec4_With_F32_F32_Vec2) {
@@ -1248,11 +1248,11 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateStatement(var));
     EXPECT_EQ(b.GenerateExpression(cast), 13u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeVector %2 2
 %3 = OpConstant %2 1
 %4 = OpConstant %2 2
@@ -1261,7 +1261,7 @@
 %8 = OpConstantNull %1
 %9 = OpTypeVector %2 4
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpStore %6 %5
 %10 = OpLoad %1 %6
 %11 = OpCompositeExtract %2 %10 0
@@ -1279,11 +1279,11 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateStatement(var));
     EXPECT_EQ(b.GenerateExpression(cast), 13u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
 %1 = OpTypeVector %2 2
 %3 = OpConstant %2 0x1p+0
 %4 = OpConstant %2 0x1p+1
@@ -1292,7 +1292,7 @@
 %8 = OpConstantNull %1
 %9 = OpTypeVector %2 4
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpStore %6 %5
 %10 = OpLoad %1 %6
 %11 = OpCompositeExtract %2 %10 0
@@ -1307,10 +1307,10 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 7u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeVector %2 4
 %3 = OpConstant %2 1
 %4 = OpConstant %2 2
@@ -1318,7 +1318,7 @@
 %6 = OpConstant %2 4
 %7 = OpConstantComposite %1 %3 %4 %5 %6
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
 }
 
 TEST_F(SpvBuilderConstructorTest, Type_Vec4_With_F16_F16_Vec2_Const) {
@@ -1329,10 +1329,10 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 7u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
 %1 = OpTypeVector %2 4
 %3 = OpConstant %2 0x1p+0
 %4 = OpConstant %2 0x1p+1
@@ -1340,7 +1340,7 @@
 %6 = OpConstant %2 0x1p+2
 %7 = OpConstantComposite %1 %3 %4 %5 %6
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
 }
 
 TEST_F(SpvBuilderConstructorTest, Type_Vec4_With_F32_Vec2_F32) {
@@ -1350,11 +1350,11 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateStatement(var));
     EXPECT_EQ(b.GenerateExpression(cast), 15u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeVector %2 2
 %3 = OpConstant %2 2
 %4 = OpConstant %2 3
@@ -1365,7 +1365,7 @@
 %10 = OpConstant %2 1
 %14 = OpConstant %2 4
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpStore %6 %5
 %11 = OpLoad %1 %6
 %12 = OpCompositeExtract %2 %11 0
@@ -1383,11 +1383,11 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateStatement(var));
     EXPECT_EQ(b.GenerateExpression(cast), 15u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
 %1 = OpTypeVector %2 2
 %3 = OpConstant %2 0x1p+1
 %4 = OpConstant %2 0x1.8p+1
@@ -1398,7 +1398,7 @@
 %10 = OpConstant %2 0x1p+0
 %14 = OpConstant %2 0x1p+2
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpStore %6 %5
 %11 = OpLoad %1 %6
 %12 = OpCompositeExtract %2 %11 0
@@ -1413,10 +1413,10 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 7u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeVector %2 4
 %3 = OpConstant %2 1
 %4 = OpConstant %2 2
@@ -1424,7 +1424,7 @@
 %6 = OpConstant %2 4
 %7 = OpConstantComposite %1 %3 %4 %5 %6
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
 }
 
 TEST_F(SpvBuilderConstructorTest, Type_Vec4_With_F16_Vec2_F16_Const) {
@@ -1435,10 +1435,10 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 7u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
 %1 = OpTypeVector %2 4
 %3 = OpConstant %2 0x1p+0
 %4 = OpConstant %2 0x1p+1
@@ -1446,7 +1446,7 @@
 %6 = OpConstant %2 0x1p+2
 %7 = OpConstantComposite %1 %3 %4 %5 %6
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
 }
 
 TEST_F(SpvBuilderConstructorTest, Type_Vec4_With_Vec2_F32_F32) {
@@ -1456,11 +1456,11 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateStatement(var));
     EXPECT_EQ(b.GenerateExpression(cast), 15u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeVector %2 2
 %3 = OpConstant %2 1
 %4 = OpConstant %2 2
@@ -1471,7 +1471,7 @@
 %13 = OpConstant %2 3
 %14 = OpConstant %2 4
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpStore %6 %5
 %10 = OpLoad %1 %6
 %11 = OpCompositeExtract %2 %10 0
@@ -1489,11 +1489,11 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateStatement(var));
     EXPECT_EQ(b.GenerateExpression(cast), 15u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
 %1 = OpTypeVector %2 2
 %3 = OpConstant %2 0x1p+0
 %4 = OpConstant %2 0x1p+1
@@ -1504,7 +1504,7 @@
 %13 = OpConstant %2 0x1.8p+1
 %14 = OpConstant %2 0x1p+2
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpStore %6 %5
 %10 = OpLoad %1 %6
 %11 = OpCompositeExtract %2 %10 0
@@ -1519,10 +1519,10 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 7u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeVector %2 4
 %3 = OpConstant %2 1
 %4 = OpConstant %2 2
@@ -1530,7 +1530,7 @@
 %6 = OpConstant %2 4
 %7 = OpConstantComposite %1 %3 %4 %5 %6
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
 }
 
 TEST_F(SpvBuilderConstructorTest, Type_Vec4_With_Vec2_F16_F16_Const) {
@@ -1541,10 +1541,10 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 7u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
 %1 = OpTypeVector %2 4
 %3 = OpConstant %2 0x1p+0
 %4 = OpConstant %2 0x1p+1
@@ -1552,7 +1552,7 @@
 %6 = OpConstant %2 0x1p+2
 %7 = OpConstantComposite %1 %3 %4 %5 %6
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
 }
 
 TEST_F(SpvBuilderConstructorTest, Type_Vec4_F32_With_Vec2_Vec2) {
@@ -1562,11 +1562,11 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateStatement(var));
     EXPECT_EQ(b.GenerateExpression(cast), 16u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeVector %2 2
 %3 = OpConstant %2 1
 %4 = OpConstant %2 2
@@ -1575,7 +1575,7 @@
 %8 = OpConstantNull %1
 %9 = OpTypeVector %2 4
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpStore %6 %5
 %10 = OpLoad %1 %6
 %11 = OpCompositeExtract %2 %10 0
@@ -1596,11 +1596,11 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateStatement(var));
     EXPECT_EQ(b.GenerateExpression(cast), 16u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
 %1 = OpTypeVector %2 2
 %3 = OpConstant %2 0x1p+0
 %4 = OpConstant %2 0x1p+1
@@ -1609,7 +1609,7 @@
 %8 = OpConstantNull %1
 %9 = OpTypeVector %2 4
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpStore %6 %5
 %10 = OpLoad %1 %6
 %11 = OpCompositeExtract %2 %10 0
@@ -1627,16 +1627,16 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 5u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeVector %2 4
 %3 = OpConstant %2 1
 %4 = OpConstant %2 2
 %5 = OpConstantComposite %1 %3 %4 %3 %4
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
 }
 
 TEST_F(SpvBuilderConstructorTest, Type_Vec4_F16_With_Vec2_Vec2_Const) {
@@ -1647,16 +1647,16 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 5u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
 %1 = OpTypeVector %2 4
 %3 = OpConstant %2 0x1p+0
 %4 = OpConstant %2 0x1p+1
 %5 = OpConstantComposite %1 %3 %4 %3 %4
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
 }
 
 TEST_F(SpvBuilderConstructorTest, Type_Vec4_With_F32_Vec3) {
@@ -1666,11 +1666,11 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateStatement(var));
     EXPECT_EQ(b.GenerateExpression(cast), 13u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeVector %2 3
 %3 = OpConstant %2 2
 %4 = OpConstantComposite %1 %3 %3 %3
@@ -1678,7 +1678,7 @@
 %7 = OpConstantNull %1
 %8 = OpTypeVector %2 4
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpStore %5 %4
 %9 = OpLoad %1 %5
 %10 = OpCompositeExtract %2 %9 0
@@ -1697,11 +1697,11 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateStatement(var));
     EXPECT_EQ(b.GenerateExpression(cast), 13u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
 %1 = OpTypeVector %2 3
 %3 = OpConstant %2 0x1p+1
 %4 = OpConstantComposite %1 %3 %3 %3
@@ -1709,7 +1709,7 @@
 %7 = OpConstantNull %1
 %8 = OpTypeVector %2 4
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpStore %5 %4
 %9 = OpLoad %1 %5
 %10 = OpCompositeExtract %2 %9 0
@@ -1725,15 +1725,15 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 4u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeVector %2 4
 %3 = OpConstant %2 2
 %4 = OpConstantComposite %1 %3 %3 %3 %3
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
 }
 
 TEST_F(SpvBuilderConstructorTest, Type_Vec4_With_F16_Vec3_Const) {
@@ -1744,15 +1744,15 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 4u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
 %1 = OpTypeVector %2 4
 %3 = OpConstant %2 0x1p+1
 %4 = OpConstantComposite %1 %3 %3 %3 %3
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
 }
 
 TEST_F(SpvBuilderConstructorTest, Type_Vec4_With_Vec3_F32) {
@@ -1762,11 +1762,11 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateStatement(var));
     EXPECT_EQ(b.GenerateExpression(cast), 13u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeVector %2 3
 %3 = OpConstant %2 2
 %4 = OpConstantComposite %1 %3 %3 %3
@@ -1774,7 +1774,7 @@
 %7 = OpConstantNull %1
 %8 = OpTypeVector %2 4
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpStore %5 %4
 %9 = OpLoad %1 %5
 %10 = OpCompositeExtract %2 %9 0
@@ -1793,11 +1793,11 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateStatement(var));
     EXPECT_EQ(b.GenerateExpression(cast), 13u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
 %1 = OpTypeVector %2 3
 %3 = OpConstant %2 0x1p+1
 %4 = OpConstantComposite %1 %3 %3 %3
@@ -1805,7 +1805,7 @@
 %7 = OpConstantNull %1
 %8 = OpTypeVector %2 4
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpStore %5 %4
 %9 = OpLoad %1 %5
 %10 = OpCompositeExtract %2 %9 0
@@ -1821,15 +1821,15 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 4u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeVector %2 4
 %3 = OpConstant %2 2
 %4 = OpConstantComposite %1 %3 %3 %3 %3
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
 }
 
 TEST_F(SpvBuilderConstructorTest, Type_Vec4_With_Vec3_F16_Const) {
@@ -1840,15 +1840,15 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 4u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
 %1 = OpTypeVector %2 4
 %3 = OpConstant %2 0x1p+1
 %4 = OpConstantComposite %1 %3 %3 %3 %3
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
 }
 
 TEST_F(SpvBuilderConstructorTest, Type_Vec4_F32_With_Vec4) {
@@ -1858,15 +1858,15 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 4u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeVector %2 4
 %3 = OpConstant %2 2
 %4 = OpConstantComposite %1 %3 %3 %3 %3
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
 }
 
 TEST_F(SpvBuilderConstructorTest, Type_Vec4_F16_With_Vec4) {
@@ -1878,15 +1878,15 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 4u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
 %1 = OpTypeVector %2 4
 %3 = OpConstant %2 0x1p+1
 %4 = OpConstantComposite %1 %3 %3 %3 %3
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
 }
 
 TEST_F(SpvBuilderConstructorTest, Type_GlobalConst_F32_With_F32) {
@@ -1897,14 +1897,14 @@
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %5 = OpTypeFloat 32
 %6 = OpConstant %5 2
 %8 = OpTypePointer Function %5
 %9 = OpConstantNull %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %7 %6
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %7 %6
 OpReturn
 )");
     Validate(b);
@@ -1920,14 +1920,14 @@
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %5 = OpTypeFloat 16
 %6 = OpConstant %5 0x1p+1
 %8 = OpTypePointer Function %5
 %9 = OpConstantNull %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %7 %6
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %7 %6
 OpReturn
 )");
     Validate(b);
@@ -1940,7 +1940,7 @@
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 32
 %2 = OpConstant %1 2
 %4 = OpTypePointer Private %1
 %3 = OpVariable %4 Private %2
@@ -1959,7 +1959,7 @@
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 16
 %2 = OpConstant %1 0x1p+1
 %4 = OpTypePointer Private %1
 %3 = OpVariable %4 Private %2
@@ -1977,14 +1977,14 @@
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %5 = OpTypeInt 32 0
 %6 = OpConstant %5 1
 %8 = OpTypePointer Function %5
 %9 = OpConstantNull %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %7 %6
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %7 %6
 OpReturn
 )");
     Validate(b);
@@ -2000,14 +2000,14 @@
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %5 = OpTypeInt 32 0
 %6 = OpConstant %5 1
 %8 = OpTypePointer Function %5
 %9 = OpConstantNull %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %7 %6
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %7 %6
 OpReturn
 )");
     Validate(b);
@@ -2020,7 +2020,7 @@
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 0
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeInt 32 0
 %2 = OpConstant %1 1
 %4 = OpTypePointer Private %1
 %3 = OpVariable %4 Private %2
@@ -2039,7 +2039,7 @@
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 0
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeInt 32 0
 %2 = OpConstant %1 1
 %4 = OpTypePointer Private %1
 %3 = OpVariable %4 Private %2
@@ -2057,7 +2057,7 @@
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %6 = OpTypeFloat 32
 %5 = OpTypeVector %6 2
@@ -2066,7 +2066,7 @@
 %10 = OpTypePointer Function %5
 %11 = OpConstantNull %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %9 %8
 OpReturn
 )");
     Validate(b);
@@ -2082,7 +2082,7 @@
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %6 = OpTypeFloat 16
 %5 = OpTypeVector %6 2
@@ -2091,7 +2091,7 @@
 %10 = OpTypePointer Function %5
 %11 = OpConstantNull %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %9 %8
 OpReturn
 )");
     Validate(b);
@@ -2103,10 +2103,10 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeVector %2 2
 %3 = OpConstant %2 2
 %4 = OpConstantComposite %1 %3 %3
@@ -2121,10 +2121,10 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
 %1 = OpTypeVector %2 2
 %3 = OpConstant %2 0x1p+1
 %4 = OpConstantComposite %1 %3 %3
@@ -2139,7 +2139,7 @@
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %6 = OpTypeFloat 32
 %5 = OpTypeVector %6 2
@@ -2148,7 +2148,7 @@
 %10 = OpTypePointer Function %5
 %11 = OpConstantNull %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %9 %8
 OpReturn
 )");
     Validate(b);
@@ -2164,7 +2164,7 @@
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %6 = OpTypeFloat 16
 %5 = OpTypeVector %6 2
@@ -2173,7 +2173,7 @@
 %10 = OpTypePointer Function %5
 %11 = OpConstantNull %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %9 %8
 OpReturn
 )");
     Validate(b);
@@ -2186,7 +2186,7 @@
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeVector %2 2
 %3 = OpConstant %2 2
 %4 = OpConstantComposite %1 %3 %3
@@ -2208,7 +2208,7 @@
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
 %1 = OpTypeVector %2 2
 %3 = OpConstant %2 0x1p+1
 %4 = OpConstantComposite %1 %3 %3
@@ -2229,7 +2229,7 @@
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %6 = OpTypeFloat 32
 %5 = OpTypeVector %6 3
@@ -2238,7 +2238,7 @@
 %10 = OpTypePointer Function %5
 %11 = OpConstantNull %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %9 %8
 OpReturn
 )");
     Validate(b);
@@ -2254,7 +2254,7 @@
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %6 = OpTypeFloat 16
 %5 = OpTypeVector %6 3
@@ -2263,7 +2263,7 @@
 %10 = OpTypePointer Function %5
 %11 = OpConstantNull %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %9 %8
 OpReturn
 )");
     Validate(b);
@@ -2276,7 +2276,7 @@
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeVector %2 3
 %3 = OpConstant %2 2
 %4 = OpConstantComposite %1 %3 %3 %3
@@ -2298,7 +2298,7 @@
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
 %1 = OpTypeVector %2 3
 %3 = OpConstant %2 0x1p+1
 %4 = OpConstantComposite %1 %3 %3 %3
@@ -2319,7 +2319,7 @@
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %6 = OpTypeFloat 32
 %5 = OpTypeVector %6 4
@@ -2328,7 +2328,7 @@
 %10 = OpTypePointer Function %5
 %11 = OpConstantNull %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %9 %8
 OpReturn
 )");
     Validate(b);
@@ -2344,7 +2344,7 @@
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %6 = OpTypeFloat 16
 %5 = OpTypeVector %6 4
@@ -2353,7 +2353,7 @@
 %10 = OpTypePointer Function %5
 %11 = OpConstantNull %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %9 %8
 OpReturn
 )");
     Validate(b);
@@ -2366,7 +2366,7 @@
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeVector %2 4
 %3 = OpConstant %2 2
 %4 = OpConstantComposite %1 %3 %3 %3 %3
@@ -2388,7 +2388,7 @@
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
 %1 = OpTypeVector %2 4
 %3 = OpConstant %2 0x1p+1
 %4 = OpConstantComposite %1 %3 %3 %3 %3
@@ -2409,7 +2409,7 @@
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %6 = OpTypeFloat 32
 %5 = OpTypeVector %6 3
@@ -2418,7 +2418,7 @@
 %10 = OpTypePointer Function %5
 %11 = OpConstantNull %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %9 %8
 OpReturn
 )");
     Validate(b);
@@ -2434,7 +2434,7 @@
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %6 = OpTypeFloat 16
 %5 = OpTypeVector %6 3
@@ -2443,7 +2443,7 @@
 %10 = OpTypePointer Function %5
 %11 = OpConstantNull %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %9 %8
 OpReturn
 )");
     Validate(b);
@@ -2455,10 +2455,10 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeVector %2 3
 %3 = OpConstant %2 2
 %4 = OpConstantComposite %1 %3 %3 %3
@@ -2473,10 +2473,10 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
 %1 = OpTypeVector %2 3
 %3 = OpConstant %2 0x1p+1
 %4 = OpConstantComposite %1 %3 %3 %3
@@ -2491,7 +2491,7 @@
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %6 = OpTypeFloat 32
 %5 = OpTypeVector %6 3
@@ -2500,7 +2500,7 @@
 %10 = OpTypePointer Function %5
 %11 = OpConstantNull %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %9 %8
 OpReturn
 )");
     Validate(b);
@@ -2516,7 +2516,7 @@
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %6 = OpTypeFloat 16
 %5 = OpTypeVector %6 3
@@ -2525,7 +2525,7 @@
 %10 = OpTypePointer Function %5
 %11 = OpConstantNull %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %9 %8
 OpReturn
 )");
     Validate(b);
@@ -2537,10 +2537,10 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeVector %2 3
 %3 = OpConstant %2 2
 %4 = OpConstantComposite %1 %3 %3 %3
@@ -2555,10 +2555,10 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
 %1 = OpTypeVector %2 3
 %3 = OpConstant %2 0x1p+1
 %4 = OpConstantComposite %1 %3 %3 %3
@@ -2573,7 +2573,7 @@
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %6 = OpTypeFloat 32
 %5 = OpTypeVector %6 3
@@ -2582,7 +2582,7 @@
 %10 = OpTypePointer Function %5
 %11 = OpConstantNull %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %9 %8
 OpReturn
 )");
     Validate(b);
@@ -2598,7 +2598,7 @@
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %6 = OpTypeFloat 16
 %5 = OpTypeVector %6 3
@@ -2607,7 +2607,7 @@
 %10 = OpTypePointer Function %5
 %11 = OpConstantNull %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %9 %8
 OpReturn
 )");
     Validate(b);
@@ -2619,10 +2619,10 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeVector %2 3
 %3 = OpConstant %2 2
 %4 = OpConstantComposite %1 %3 %3 %3
@@ -2637,10 +2637,10 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
 %1 = OpTypeVector %2 3
 %3 = OpConstant %2 0x1p+1
 %4 = OpConstantComposite %1 %3 %3 %3
@@ -2655,7 +2655,7 @@
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %6 = OpTypeFloat 32
 %5 = OpTypeVector %6 4
@@ -2664,7 +2664,7 @@
 %10 = OpTypePointer Function %5
 %11 = OpConstantNull %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %9 %8
 OpReturn
 )");
     Validate(b);
@@ -2680,7 +2680,7 @@
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %6 = OpTypeFloat 16
 %5 = OpTypeVector %6 4
@@ -2689,7 +2689,7 @@
 %10 = OpTypePointer Function %5
 %11 = OpConstantNull %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %9 %8
 OpReturn
 )");
     Validate(b);
@@ -2701,10 +2701,10 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeVector %2 4
 %3 = OpConstant %2 2
 %4 = OpConstantComposite %1 %3 %3 %3 %3
@@ -2719,10 +2719,10 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
 %1 = OpTypeVector %2 4
 %3 = OpConstant %2 0x1p+1
 %4 = OpConstantComposite %1 %3 %3 %3 %3
@@ -2737,7 +2737,7 @@
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %6 = OpTypeFloat 32
 %5 = OpTypeVector %6 4
@@ -2746,7 +2746,7 @@
 %10 = OpTypePointer Function %5
 %11 = OpConstantNull %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %9 %8
 OpReturn
 )");
     Validate(b);
@@ -2762,7 +2762,7 @@
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %6 = OpTypeFloat 16
 %5 = OpTypeVector %6 4
@@ -2771,7 +2771,7 @@
 %10 = OpTypePointer Function %5
 %11 = OpConstantNull %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %9 %8
 OpReturn
 )");
     Validate(b);
@@ -2783,10 +2783,10 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeVector %2 4
 %3 = OpConstant %2 2
 %4 = OpConstantComposite %1 %3 %3 %3 %3
@@ -2801,10 +2801,10 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
 %1 = OpTypeVector %2 4
 %3 = OpConstant %2 0x1p+1
 %4 = OpConstantComposite %1 %3 %3 %3 %3
@@ -2819,7 +2819,7 @@
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %6 = OpTypeFloat 32
 %5 = OpTypeVector %6 4
@@ -2828,7 +2828,7 @@
 %10 = OpTypePointer Function %5
 %11 = OpConstantNull %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %9 %8
 OpReturn
 )");
     Validate(b);
@@ -2844,7 +2844,7 @@
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %6 = OpTypeFloat 16
 %5 = OpTypeVector %6 4
@@ -2853,7 +2853,7 @@
 %10 = OpTypePointer Function %5
 %11 = OpConstantNull %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %9 %8
 OpReturn
 )");
     Validate(b);
@@ -2865,10 +2865,10 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeVector %2 4
 %3 = OpConstant %2 2
 %4 = OpConstantComposite %1 %3 %3 %3 %3
@@ -2883,10 +2883,10 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
 %1 = OpTypeVector %2 4
 %3 = OpConstant %2 0x1p+1
 %4 = OpConstantComposite %1 %3 %3 %3 %3
@@ -2901,7 +2901,7 @@
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %6 = OpTypeFloat 32
 %5 = OpTypeVector %6 4
@@ -2910,7 +2910,7 @@
 %10 = OpTypePointer Function %5
 %11 = OpConstantNull %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %9 %8
 OpReturn
 )");
     Validate(b);
@@ -2926,7 +2926,7 @@
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %6 = OpTypeFloat 16
 %5 = OpTypeVector %6 4
@@ -2935,7 +2935,7 @@
 %10 = OpTypePointer Function %5
 %11 = OpConstantNull %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %9 %8
 OpReturn
 )");
     Validate(b);
@@ -2947,10 +2947,10 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeVector %2 4
 %3 = OpConstant %2 2
 %4 = OpConstantComposite %1 %3 %3 %3 %3
@@ -2965,10 +2965,10 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
 %1 = OpTypeVector %2 4
 %3 = OpConstant %2 0x1p+1
 %4 = OpConstantComposite %1 %3 %3 %3 %3
@@ -2983,7 +2983,7 @@
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %6 = OpTypeFloat 32
 %5 = OpTypeVector %6 4
@@ -2992,7 +2992,7 @@
 %10 = OpTypePointer Function %5
 %11 = OpConstantNull %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %9 %8
 OpReturn
 )");
     Validate(b);
@@ -3008,7 +3008,7 @@
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %6 = OpTypeFloat 16
 %5 = OpTypeVector %6 4
@@ -3017,7 +3017,7 @@
 %10 = OpTypePointer Function %5
 %11 = OpConstantNull %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %9 %8
 OpReturn
 )");
     Validate(b);
@@ -3029,10 +3029,10 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeVector %2 4
 %3 = OpConstant %2 2
 %4 = OpConstantComposite %1 %3 %3 %3 %3
@@ -3047,10 +3047,10 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
 %1 = OpTypeVector %2 4
 %3 = OpConstant %2 0x1p+1
 %4 = OpConstantComposite %1 %3 %3 %3 %3
@@ -3065,7 +3065,7 @@
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %6 = OpTypeFloat 32
 %5 = OpTypeVector %6 4
@@ -3074,7 +3074,7 @@
 %10 = OpTypePointer Function %5
 %11 = OpConstantNull %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %9 %8
 OpReturn
 )");
     Validate(b);
@@ -3086,10 +3086,10 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeVector %2 4
 %3 = OpConstant %2 2
 %4 = OpConstantComposite %1 %3 %3 %3 %3
@@ -3104,10 +3104,10 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
 %1 = OpTypeVector %2 4
 %3 = OpConstant %2 0x1p+1
 %4 = OpConstantComposite %1 %3 %3 %3 %3
@@ -3122,7 +3122,7 @@
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %6 = OpTypeFloat 32
 %5 = OpTypeVector %6 4
@@ -3131,7 +3131,7 @@
 %10 = OpTypePointer Function %5
 %11 = OpConstantNull %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %9 %8
 OpReturn
 )");
     Validate(b);
@@ -3147,7 +3147,7 @@
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %6 = OpTypeFloat 16
 %5 = OpTypeVector %6 4
@@ -3156,7 +3156,7 @@
 %10 = OpTypePointer Function %5
 %11 = OpConstantNull %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %9 %8
 OpReturn
 )");
     Validate(b);
@@ -3168,10 +3168,10 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeVector %2 4
 %3 = OpConstant %2 2
 %4 = OpConstantComposite %1 %3 %3 %3 %3
@@ -3186,10 +3186,10 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
 %1 = OpTypeVector %2 4
 %3 = OpConstant %2 0x1p+1
 %4 = OpConstantComposite %1 %3 %3 %3 %3
@@ -3202,10 +3202,10 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 6u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 32
 %2 = OpTypeVector %3 2
 %1 = OpTypeMatrix %2 2
 %4 = OpConstant %3 2
@@ -3222,10 +3222,10 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 6u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 16
 %2 = OpTypeVector %3 2
 %1 = OpTypeMatrix %2 2
 %4 = OpConstant %3 0x1p+1
@@ -3240,10 +3240,10 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 6u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 32
 %2 = OpTypeVector %3 2
 %1 = OpTypeMatrix %2 3
 %4 = OpConstant %3 2
@@ -3260,10 +3260,10 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 6u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 16
 %2 = OpTypeVector %3 2
 %1 = OpTypeMatrix %2 3
 %4 = OpConstant %3 0x1p+1
@@ -3279,10 +3279,10 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 6u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 32
 %2 = OpTypeVector %3 2
 %1 = OpTypeMatrix %2 4
 %4 = OpConstant %3 2
@@ -3300,10 +3300,10 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 6u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 16
 %2 = OpTypeVector %3 2
 %1 = OpTypeMatrix %2 4
 %4 = OpConstant %3 0x1p+1
@@ -3318,10 +3318,10 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 6u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 32
 %2 = OpTypeVector %3 3
 %1 = OpTypeMatrix %2 2
 %4 = OpConstant %3 2
@@ -3338,10 +3338,10 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 6u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 16
 %2 = OpTypeVector %3 3
 %1 = OpTypeMatrix %2 2
 %4 = OpConstant %3 0x1p+1
@@ -3357,10 +3357,10 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 6u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 32
 %2 = OpTypeVector %3 3
 %1 = OpTypeMatrix %2 3
 %4 = OpConstant %3 2
@@ -3378,10 +3378,10 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 6u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 16
 %2 = OpTypeVector %3 3
 %1 = OpTypeMatrix %2 3
 %4 = OpConstant %3 0x1p+1
@@ -3397,10 +3397,10 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 6u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 32
 %2 = OpTypeVector %3 3
 %1 = OpTypeMatrix %2 4
 %4 = OpConstant %3 2
@@ -3418,10 +3418,10 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 6u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 16
 %2 = OpTypeVector %3 3
 %1 = OpTypeMatrix %2 4
 %4 = OpConstant %3 0x1p+1
@@ -3436,10 +3436,10 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 6u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 32
 %2 = OpTypeVector %3 4
 %1 = OpTypeMatrix %2 2
 %4 = OpConstant %3 2
@@ -3456,10 +3456,10 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 6u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 16
 %2 = OpTypeVector %3 4
 %1 = OpTypeMatrix %2 2
 %4 = OpConstant %3 0x1p+1
@@ -3475,10 +3475,10 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 6u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 32
 %2 = OpTypeVector %3 4
 %1 = OpTypeMatrix %2 3
 %4 = OpConstant %3 2
@@ -3496,10 +3496,10 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 6u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 16
 %2 = OpTypeVector %3 4
 %1 = OpTypeMatrix %2 3
 %4 = OpConstant %3 0x1p+1
@@ -3515,10 +3515,10 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 6u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 32
 %2 = OpTypeVector %3 4
 %1 = OpTypeMatrix %2 4
 %4 = OpConstant %3 2
@@ -3536,10 +3536,10 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 6u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 16
 %2 = OpTypeVector %3 4
 %1 = OpTypeMatrix %2 4
 %4 = OpConstant %3 0x1p+1
@@ -3554,10 +3554,10 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 6u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %3 = OpTypeInt 32 0
 %4 = OpConstant %3 5
 %1 = OpTypeArray %2 %4
@@ -3574,10 +3574,10 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(cast), 6u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
 %3 = OpTypeInt 32 0
 %4 = OpConstant %3 5
 %1 = OpTypeArray %2 %4
@@ -3593,9 +3593,9 @@
     WrapInFunction(t);
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(t), 10u);
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 32
 %2 = OpTypeVector %3 3
 %4 = OpTypeInt 32 0
 %5 = OpConstant %4 2
@@ -3617,9 +3617,9 @@
     WrapInFunction(t);
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(t), 10u);
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 16
 %2 = OpTypeVector %3 3
 %4 = OpTypeInt 32 0
 %5 = OpConstant %4 2
@@ -3639,11 +3639,11 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(v1), 4u);
     EXPECT_EQ(b.GenerateExpression(v2), 4u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeVector %2 3
 %3 = OpConstant %2 2
 %4 = OpConstantComposite %1 %3 %3 %3
@@ -3657,11 +3657,11 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(a1), 6u);
     EXPECT_EQ(b.GenerateExpression(a2), 6u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %3 = OpTypeInt 32 0
 %4 = OpConstant %3 3
 %1 = OpTypeArray %2 %4
@@ -3679,11 +3679,11 @@
     WrapInFunction(WrapInStatement(a1), WrapInStatement(a2));
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateExpression(a1), 7u);
     EXPECT_EQ(b.GenerateExpression(a2), 9u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %3 = OpTypeInt 32 0
 %4 = OpConstant %3 2
 %1 = OpTypeArray %2 %4
@@ -3706,12 +3706,12 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
 
     EXPECT_EQ(b.GenerateExpression(t), 6u);
     ASSERT_FALSE(b.has_error()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %3 = OpTypeVector %2 3
 %1 = OpTypeStruct %2 %3
 %4 = OpConstant %2 2
@@ -3727,12 +3727,12 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
 
     EXPECT_EQ(b.GenerateExpression(t), 2u);
     ASSERT_FALSE(b.has_error()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 32
 %2 = OpConstantNull %1
 )");
 }
@@ -3746,12 +3746,12 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
 
     EXPECT_EQ(b.GenerateExpression(t), 2u);
     ASSERT_FALSE(b.has_error()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 16
 %2 = OpConstantNull %1
 )");
 }
@@ -3763,12 +3763,12 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
 
     EXPECT_EQ(b.GenerateExpression(t), 2u);
     ASSERT_FALSE(b.has_error()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 1
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeInt 32 1
 %2 = OpConstantNull %1
 )");
 }
@@ -3780,12 +3780,12 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
 
     EXPECT_EQ(b.GenerateExpression(t), 2u);
     ASSERT_FALSE(b.has_error()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 0
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeInt 32 0
 %2 = OpConstantNull %1
 )");
 }
@@ -3797,12 +3797,12 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
 
     EXPECT_EQ(b.GenerateExpression(t), 2u);
     ASSERT_FALSE(b.has_error()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeBool
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeBool
 %2 = OpConstantNull %1
 )");
 }
@@ -3814,12 +3814,12 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
 
     EXPECT_EQ(b.GenerateExpression(t), 3u);
     ASSERT_FALSE(b.has_error()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 1
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeInt 32 1
 %1 = OpTypeVector %2 2
 %3 = OpConstantNull %1
 )");
@@ -3832,12 +3832,12 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
 
     EXPECT_EQ(b.GenerateExpression(t), 4u);
     ASSERT_FALSE(b.has_error()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 32
 %2 = OpTypeVector %3 2
 %1 = OpTypeMatrix %2 4
 %4 = OpConstantNull %1
@@ -3853,12 +3853,12 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
 
     EXPECT_EQ(b.GenerateExpression(t), 4u);
     ASSERT_FALSE(b.has_error()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 16
 %2 = OpTypeVector %3 2
 %1 = OpTypeMatrix %2 4
 %4 = OpConstantNull %1
@@ -3872,12 +3872,12 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
 
     EXPECT_EQ(b.GenerateExpression(t), 5u);
     ASSERT_FALSE(b.has_error()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 1
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeInt 32 1
 %3 = OpTypeInt 32 0
 %4 = OpConstant %3 2
 %1 = OpTypeArray %2 %4
@@ -3892,12 +3892,12 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
 
     EXPECT_EQ(b.GenerateExpression(t), 3u);
     ASSERT_FALSE(b.has_error()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeStruct %2
 %3 = OpConstantNull %1
 )");
@@ -3910,17 +3910,17 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateStatement(var)) << b.error();
     EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 0
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeInt 32 0
 %2 = OpConstant %1 2
 %4 = OpTypePointer Function %1
 %5 = OpConstantNull %1
 %7 = OpTypeInt 32 1
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpStore %3 %2
 %8 = OpLoad %1 %3
 %6 = OpBitcast %7 %8
@@ -3934,17 +3934,17 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateStatement(var)) << b.error();
     EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 32
 %2 = OpConstant %1 2.4000001
 %4 = OpTypePointer Function %1
 %5 = OpConstantNull %1
 %7 = OpTypeInt 32 1
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpStore %3 %2
 %8 = OpLoad %1 %3
 %6 = OpConvertFToS %7 %8
@@ -3960,17 +3960,17 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateStatement(var)) << b.error();
     EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 16
 %2 = OpConstant %1 0x1.33p+1
 %4 = OpTypePointer Function %1
 %5 = OpConstantNull %1
 %7 = OpTypeInt 32 1
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpStore %3 %2
 %8 = OpLoad %1 %3
 %6 = OpConvertFToS %7 %8
@@ -3984,17 +3984,17 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateStatement(var)) << b.error();
     EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 1
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeInt 32 1
 %2 = OpConstant %1 2
 %4 = OpTypePointer Function %1
 %5 = OpConstantNull %1
 %7 = OpTypeInt 32 0
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpStore %3 %2
 %8 = OpLoad %1 %3
 %6 = OpBitcast %7 %8
@@ -4008,17 +4008,17 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateStatement(var)) << b.error();
     EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 32
 %2 = OpConstant %1 2.4000001
 %4 = OpTypePointer Function %1
 %5 = OpConstantNull %1
 %7 = OpTypeInt 32 0
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpStore %3 %2
 %8 = OpLoad %1 %3
 %6 = OpConvertFToU %7 %8
@@ -4034,17 +4034,17 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateStatement(var)) << b.error();
     EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 16
 %2 = OpConstant %1 0x1.33p+1
 %4 = OpTypePointer Function %1
 %5 = OpConstantNull %1
 %7 = OpTypeInt 32 0
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpStore %3 %2
 %8 = OpLoad %1 %3
 %6 = OpConvertFToU %7 %8
@@ -4058,17 +4058,17 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateStatement(var)) << b.error();
     EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 1
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeInt 32 1
 %2 = OpConstant %1 2
 %4 = OpTypePointer Function %1
 %5 = OpConstantNull %1
 %7 = OpTypeFloat 32
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpStore %3 %2
 %8 = OpLoad %1 %3
 %6 = OpConvertSToF %7 %8
@@ -4082,17 +4082,17 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateStatement(var)) << b.error();
     EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 0
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeInt 32 0
 %2 = OpConstant %1 2
 %4 = OpTypePointer Function %1
 %5 = OpConstantNull %1
 %7 = OpTypeFloat 32
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpStore %3 %2
 %8 = OpLoad %1 %3
 %6 = OpConvertUToF %7 %8
@@ -4108,17 +4108,17 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateStatement(var)) << b.error();
     EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 16
 %2 = OpConstant %1 0x1p+1
 %4 = OpTypePointer Function %1
 %5 = OpConstantNull %1
 %7 = OpTypeFloat 32
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpStore %3 %2
 %8 = OpLoad %1 %3
 %6 = OpFConvert %7 %8
@@ -4134,17 +4134,17 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateStatement(var)) << b.error();
     EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 1
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeInt 32 1
 %2 = OpConstant %1 2
 %4 = OpTypePointer Function %1
 %5 = OpConstantNull %1
 %7 = OpTypeFloat 16
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpStore %3 %2
 %8 = OpLoad %1 %3
 %6 = OpConvertSToF %7 %8
@@ -4160,17 +4160,17 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateStatement(var)) << b.error();
     EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 0
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeInt 32 0
 %2 = OpConstant %1 2
 %4 = OpTypePointer Function %1
 %5 = OpConstantNull %1
 %7 = OpTypeFloat 16
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpStore %3 %2
 %8 = OpLoad %1 %3
 %6 = OpConvertUToF %7 %8
@@ -4186,17 +4186,17 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateStatement(var)) << b.error();
     EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 32
 %2 = OpConstant %1 2
 %4 = OpTypePointer Function %1
 %5 = OpConstantNull %1
 %7 = OpTypeFloat 16
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpStore %3 %2
 %8 = OpLoad %1 %3
 %6 = OpFConvert %7 %8
@@ -4211,11 +4211,11 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
     EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeInt 32 0
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeInt 32 0
 %3 = OpTypeVector %4 3
 %2 = OpTypePointer Private %3
 %5 = OpConstantNull %3
@@ -4223,7 +4223,7 @@
 %8 = OpTypeInt 32 1
 %7 = OpTypeVector %8 3
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(%9 = OpLoad %3 %1
 %6 = OpBitcast %7 %9
 )");
@@ -4237,11 +4237,11 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
     EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeFloat 32
 %3 = OpTypeVector %4 3
 %2 = OpTypePointer Private %3
 %5 = OpConstantNull %3
@@ -4249,7 +4249,7 @@
 %8 = OpTypeInt 32 1
 %7 = OpTypeVector %8 3
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(%9 = OpLoad %3 %1
 %6 = OpConvertFToS %7 %9
 )");
@@ -4265,11 +4265,11 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
     EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeFloat 16
 %3 = OpTypeVector %4 3
 %2 = OpTypePointer Private %3
 %5 = OpConstantNull %3
@@ -4277,7 +4277,7 @@
 %8 = OpTypeInt 32 1
 %7 = OpTypeVector %8 3
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(%9 = OpLoad %3 %1
 %6 = OpConvertFToS %7 %9
 )");
@@ -4291,11 +4291,11 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
     EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeInt 32 1
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeInt 32 1
 %3 = OpTypeVector %4 3
 %2 = OpTypePointer Private %3
 %5 = OpConstantNull %3
@@ -4303,7 +4303,7 @@
 %8 = OpTypeInt 32 0
 %7 = OpTypeVector %8 3
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(%9 = OpLoad %3 %1
 %6 = OpBitcast %7 %9
 )");
@@ -4317,11 +4317,11 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
     EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeFloat 32
 %3 = OpTypeVector %4 3
 %2 = OpTypePointer Private %3
 %5 = OpConstantNull %3
@@ -4329,7 +4329,7 @@
 %8 = OpTypeInt 32 0
 %7 = OpTypeVector %8 3
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(%9 = OpLoad %3 %1
 %6 = OpConvertFToU %7 %9
 )");
@@ -4345,11 +4345,11 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
     EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeFloat 16
 %3 = OpTypeVector %4 3
 %2 = OpTypePointer Private %3
 %5 = OpConstantNull %3
@@ -4357,7 +4357,7 @@
 %8 = OpTypeInt 32 0
 %7 = OpTypeVector %8 3
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(%9 = OpLoad %3 %1
 %6 = OpConvertFToU %7 %9
 )");
@@ -4371,11 +4371,11 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
     EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeInt 32 1
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeInt 32 1
 %3 = OpTypeVector %4 3
 %2 = OpTypePointer Private %3
 %5 = OpConstantNull %3
@@ -4383,7 +4383,7 @@
 %8 = OpTypeFloat 32
 %7 = OpTypeVector %8 3
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(%9 = OpLoad %3 %1
 %6 = OpConvertSToF %7 %9
 )");
@@ -4397,11 +4397,11 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
     EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeInt 32 0
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeInt 32 0
 %3 = OpTypeVector %4 3
 %2 = OpTypePointer Private %3
 %5 = OpConstantNull %3
@@ -4409,7 +4409,7 @@
 %8 = OpTypeFloat 32
 %7 = OpTypeVector %8 3
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(%9 = OpLoad %3 %1
 %6 = OpConvertUToF %7 %9
 )");
@@ -4425,11 +4425,11 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
     EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeFloat 16
 %3 = OpTypeVector %4 3
 %2 = OpTypePointer Private %3
 %5 = OpConstantNull %3
@@ -4437,7 +4437,7 @@
 %8 = OpTypeFloat 32
 %7 = OpTypeVector %8 3
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(%9 = OpLoad %3 %1
 %6 = OpFConvert %7 %9
 )");
@@ -4453,11 +4453,11 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
     EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeInt 32 1
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeInt 32 1
 %3 = OpTypeVector %4 3
 %2 = OpTypePointer Private %3
 %5 = OpConstantNull %3
@@ -4465,7 +4465,7 @@
 %8 = OpTypeFloat 16
 %7 = OpTypeVector %8 3
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(%9 = OpLoad %3 %1
 %6 = OpConvertSToF %7 %9
 )");
@@ -4481,11 +4481,11 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
     EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeInt 32 0
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeInt 32 0
 %3 = OpTypeVector %4 3
 %2 = OpTypePointer Private %3
 %5 = OpConstantNull %3
@@ -4493,7 +4493,7 @@
 %8 = OpTypeFloat 16
 %7 = OpTypeVector %8 3
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(%9 = OpLoad %3 %1
 %6 = OpConvertUToF %7 %9
 )");
@@ -4509,11 +4509,11 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
     EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeFloat 32
 %3 = OpTypeVector %4 3
 %2 = OpTypePointer Private %3
 %5 = OpConstantNull %3
@@ -4521,7 +4521,7 @@
 %8 = OpTypeFloat 16
 %7 = OpTypeVector %8 3
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(%9 = OpLoad %3 %1
 %6 = OpFConvert %7 %9
 )");
diff --git a/src/tint/writer/spirv/builder_discard_test.cc b/src/tint/writer/spirv/builder_discard_test.cc
index 747b85c..a268d95 100644
--- a/src/tint/writer/spirv/builder_discard_test.cc
+++ b/src/tint/writer/spirv/builder_discard_test.cc
@@ -28,9 +28,9 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateStatement(stmt)) << b.error();
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpKill
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"(OpKill
 )");
 }
 
diff --git a/src/tint/writer/spirv/builder_entry_point_test.cc b/src/tint/writer/spirv/builder_entry_point_test.cc
index 085a6f2..406b3db 100644
--- a/src/tint/writer/spirv/builder_entry_point_test.cc
+++ b/src/tint/writer/spirv/builder_entry_point_test.cc
@@ -333,11 +333,11 @@
     ASSERT_TRUE(b.Build()) << b.error();
 
     // Make sure we generate the SampleRateShading capability.
-    EXPECT_EQ(DumpInstructions(b.capabilities()),
+    EXPECT_EQ(DumpInstructions(b.Module().Capabilities()),
               R"(OpCapability Shader
 OpCapability SampleRateShading
 )");
-    EXPECT_EQ(DumpInstructions(b.annots()), R"(OpDecorate %1 BuiltIn SampleId
+    EXPECT_EQ(DumpInstructions(b.Module().Annots()), R"(OpDecorate %1 BuiltIn SampleId
 OpDecorate %1 Flat
 )");
 }
diff --git a/src/tint/writer/spirv/builder_format_conversion_test.cc b/src/tint/writer/spirv/builder_format_conversion_test.cc
index 1efdcca..6bd075d 100644
--- a/src/tint/writer/spirv/builder_format_conversion_test.cc
+++ b/src/tint/writer/spirv/builder_format_conversion_test.cc
@@ -39,11 +39,11 @@
     EXPECT_EQ(b.convert_texel_format_to_spv(param.ast_format), param.spv_format);
 
     if (param.extended_format) {
-        EXPECT_EQ(DumpInstructions(b.capabilities()),
+        EXPECT_EQ(DumpInstructions(b.Module().Capabilities()),
                   R"(OpCapability StorageImageExtendedFormats
 )");
     } else {
-        EXPECT_EQ(DumpInstructions(b.capabilities()), "");
+        EXPECT_EQ(DumpInstructions(b.Module().Capabilities()), "");
     }
 }
 
diff --git a/src/tint/writer/spirv/builder_function_attribute_test.cc b/src/tint/writer/spirv/builder_function_attribute_test.cc
index 1b23982..f4de7f5 100644
--- a/src/tint/writer/spirv/builder_function_attribute_test.cc
+++ b/src/tint/writer/spirv/builder_function_attribute_test.cc
@@ -33,7 +33,7 @@
     spirv::Builder& b = Build();
 
     ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
-    EXPECT_EQ(DumpInstructions(b.entry_points()),
+    EXPECT_EQ(DumpInstructions(b.Module().EntryPoints()),
               R"(OpEntryPoint Fragment %3 "main"
 )");
 }
@@ -76,7 +76,7 @@
     }
     ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
 
-    auto preamble = b.entry_points();
+    auto preamble = b.Module().EntryPoints();
     ASSERT_GE(preamble.size(), 1u);
     EXPECT_EQ(preamble[0].opcode(), spv::Op::OpEntryPoint);
 
@@ -99,7 +99,7 @@
     spirv::Builder& b = Build();
 
     ASSERT_TRUE(b.GenerateExecutionModes(func, 3)) << b.error();
-    EXPECT_EQ(DumpInstructions(b.execution_modes()),
+    EXPECT_EQ(DumpInstructions(b.Module().ExecutionModes()),
               R"(OpExecutionMode %3 OriginUpperLeft
 )");
 }
@@ -111,7 +111,7 @@
     spirv::Builder& b = Build();
 
     ASSERT_TRUE(b.GenerateExecutionModes(func, 3)) << b.error();
-    EXPECT_EQ(DumpInstructions(b.execution_modes()),
+    EXPECT_EQ(DumpInstructions(b.Module().ExecutionModes()),
               R"(OpExecutionMode %3 LocalSize 1 1 1
 )");
 }
@@ -126,7 +126,7 @@
     spirv::Builder& b = Build();
 
     ASSERT_TRUE(b.GenerateExecutionModes(func, 3)) << b.error();
-    EXPECT_EQ(DumpInstructions(b.execution_modes()),
+    EXPECT_EQ(DumpInstructions(b.Module().ExecutionModes()),
               R"(OpExecutionMode %3 LocalSize 2 4 6
 )");
 }
@@ -144,7 +144,7 @@
     spirv::Builder& b = Build();
 
     ASSERT_TRUE(b.GenerateExecutionModes(func, 3)) << b.error();
-    EXPECT_EQ(DumpInstructions(b.execution_modes()),
+    EXPECT_EQ(DumpInstructions(b.Module().ExecutionModes()),
               R"(OpExecutionMode %3 LocalSize 2 3 4
 )");
 }
@@ -235,7 +235,7 @@
 
     ASSERT_TRUE(b.Build());
 
-    EXPECT_EQ(DumpInstructions(b.execution_modes()),
+    EXPECT_EQ(DumpInstructions(b.Module().ExecutionModes()),
               R"(OpExecutionMode %11 OriginUpperLeft
 OpExecutionMode %11 DepthReplacing
 )");
diff --git a/src/tint/writer/spirv/builder_function_test.cc b/src/tint/writer/spirv/builder_function_test.cc
index 5cf97ea..1cab162 100644
--- a/src/tint/writer/spirv/builder_function_test.cc
+++ b/src/tint/writer/spirv/builder_function_test.cc
@@ -161,7 +161,7 @@
 
     auto* func = program->AST().Functions()[0];
     ASSERT_TRUE(b.GenerateFunction(func));
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 )");
 }
@@ -174,7 +174,7 @@
 
     ASSERT_TRUE(b.GenerateFunction(func1));
     ASSERT_TRUE(b.GenerateFunction(func2));
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 )");
 }
diff --git a/src/tint/writer/spirv/builder_function_variable_test.cc b/src/tint/writer/spirv/builder_function_variable_test.cc
index 72cf12b..354ad66 100644
--- a/src/tint/writer/spirv/builder_function_variable_test.cc
+++ b/src/tint/writer/spirv/builder_function_variable_test.cc
@@ -28,16 +28,16 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateFunctionVariable(v)) << b.error();
-    EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
+    EXPECT_EQ(DumpInstructions(b.Module().Debug()), R"(OpName %1 "var"
 )");
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 32
 %2 = OpTypePointer Function %3
 %4 = OpConstantNull %3
 )");
 
-    const auto& func = b.functions()[0];
+    const auto& func = b.CurrentFunction();
     EXPECT_EQ(DumpInstructions(func.variables()),
               R"(%1 = OpVariable %2 Function %4
 )");
@@ -50,13 +50,13 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateFunctionVariable(v)) << b.error();
     ASSERT_FALSE(b.has_error()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %6 "var"
+    EXPECT_EQ(DumpInstructions(b.Module().Debug()), R"(OpName %6 "var"
 )");
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeVector %2 3
 %3 = OpConstant %2 1
 %4 = OpConstant %2 3
@@ -64,10 +64,10 @@
 %7 = OpTypePointer Function %1
 %8 = OpConstantNull %1
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().variables()),
               R"(%6 = OpVariable %7 Function %8
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpStore %6 %5
 )");
 }
@@ -81,24 +81,24 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateFunctionVariable(a)) << b.error();
     EXPECT_TRUE(b.GenerateFunctionVariable(v)) << b.error();
     ASSERT_FALSE(b.has_error()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %7 "var"
+    EXPECT_EQ(DumpInstructions(b.Module().Debug()), R"(OpName %7 "var"
 )");
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 32
 %2 = OpConstant %1 3
 %3 = OpTypeVector %1 2
 %4 = OpConstant %1 1
 %8 = OpTypePointer Function %3
 %9 = OpConstantNull %3
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().variables()),
               R"(%7 = OpVariable %8 Function %9
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(%5 = OpFAdd %1 %2 %2
 %6 = OpCompositeConstruct %3 %4 %5
 OpStore %7 %6
@@ -116,24 +116,24 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateFunctionVariable(v)) << b.error();
     EXPECT_TRUE(b.GenerateFunctionVariable(v2)) << b.error();
     ASSERT_FALSE(b.has_error()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %3 "v"
+    EXPECT_EQ(DumpInstructions(b.Module().Debug()), R"(OpName %3 "v"
 OpName %7 "v2"
 )");
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 32
 %2 = OpConstant %1 1
 %4 = OpTypePointer Function %1
 %5 = OpConstantNull %1
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().variables()),
               R"(%3 = OpVariable %4 Function %5
 %7 = OpVariable %4 Function %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpStore %3 %2
 %6 = OpLoad %1 %3
 OpStore %7 %6
@@ -151,24 +151,24 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateFunctionVariable(v)) << b.error();
     EXPECT_TRUE(b.GenerateFunctionVariable(v2)) << b.error();
     ASSERT_FALSE(b.has_error()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %3 "v"
+    EXPECT_EQ(DumpInstructions(b.Module().Debug()), R"(OpName %3 "v"
 OpName %7 "v2"
 )");
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 32
 %2 = OpConstant %1 1
 %4 = OpTypePointer Function %1
 %5 = OpConstantNull %1
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().variables()),
               R"(%3 = OpVariable %4 Function %5
 %7 = OpVariable %4 Function %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpStore %3 %2
 %6 = OpLoad %1 %3
 OpStore %7 %6
@@ -186,22 +186,22 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateFunctionVariable(v)) << b.error();
     EXPECT_TRUE(b.GenerateFunctionVariable(v2)) << b.error();
     ASSERT_FALSE(b.has_error()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %3 "v2"
+    EXPECT_EQ(DumpInstructions(b.Module().Debug()), R"(OpName %3 "v2"
 )");
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 32
 %2 = OpConstant %1 1
 %4 = OpTypePointer Function %1
 %5 = OpConstantNull %1
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().variables()),
               R"(%3 = OpVariable %4 Function %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpStore %3 %2
 )");
 }
@@ -218,7 +218,7 @@
     EXPECT_TRUE(b.GenerateFunctionVariable(v)) << b.error();
     ASSERT_FALSE(b.has_error()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeVector %2 3
 %3 = OpConstant %2 1
 %4 = OpConstant %2 3
@@ -238,7 +238,7 @@
     EXPECT_TRUE(b.GenerateFunctionVariable(v)) << b.error();
     ASSERT_FALSE(b.has_error()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), "");  // Not a mistake - 'const' is inlined
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), "");  // Not a mistake - 'const' is inlined
 }
 
 }  // namespace
diff --git a/src/tint/writer/spirv/builder_global_variable_test.cc b/src/tint/writer/spirv/builder_global_variable_test.cc
index 569d5e9..27c2402 100644
--- a/src/tint/writer/spirv/builder_global_variable_test.cc
+++ b/src/tint/writer/spirv/builder_global_variable_test.cc
@@ -31,9 +31,9 @@
     spirv::Builder& b = Build();
 
     EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
-    EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
+    EXPECT_EQ(DumpInstructions(b.Module().Debug()), R"(OpName %1 "var"
 )");
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 32
 %2 = OpTypePointer Private %3
 %4 = OpConstantNull %3
 %1 = OpVariable %2 Private %4
@@ -50,9 +50,9 @@
     EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
     ASSERT_FALSE(b.has_error()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %6 "var"
+    EXPECT_EQ(DumpInstructions(b.Module().Debug()), R"(OpName %6 "var"
 )");
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeVector %2 3
 %3 = OpConstant %2 1
 %4 = OpConstant %2 3
@@ -73,15 +73,15 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 1
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeInt 32 1
 %2 = OpConstant %1 42
 %4 = OpTypePointer Private %1
 %3 = OpVariable %4 Private %2
 %6 = OpTypeVoid
 %5 = OpTypeFunction %6
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"()");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpReturn
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()), R"()");
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpReturn
 )");
 
     Validate(b);
@@ -98,7 +98,7 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeVector %2 3
 %3 = OpConstant %2 1
 %4 = OpConstant %2 2
@@ -109,8 +109,8 @@
 %10 = OpTypeVoid
 %9 = OpTypeFunction %10
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"()");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpReturn
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()), R"()");
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpReturn
 )");
 
     Validate(b);
@@ -128,7 +128,7 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
 %1 = OpTypeVector %2 3
 %3 = OpConstant %2 0x1p+0
 %4 = OpConstant %2 0x1p+1
@@ -139,8 +139,8 @@
 %10 = OpTypeVoid
 %9 = OpTypeFunction %10
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"()");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpReturn
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()), R"()");
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpReturn
 )");
 
     Validate(b);
@@ -157,7 +157,7 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 1
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeInt 32 1
 %1 = OpTypeVector %2 3
 %3 = OpConstant %2 1
 %4 = OpConstant %2 2
@@ -168,8 +168,8 @@
 %10 = OpTypeVoid
 %9 = OpTypeFunction %10
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"()");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpReturn
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()), R"()");
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpReturn
 )");
 
     Validate(b);
@@ -186,7 +186,7 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeVector %2 3
 %3 = OpConstant %2 1
 %4 = OpConstant %2 2
@@ -197,8 +197,8 @@
 %10 = OpTypeVoid
 %9 = OpTypeFunction %10
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"()");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpReturn
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()), R"()");
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpReturn
 )");
 
     Validate(b);
@@ -215,7 +215,7 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeVector %2 3
 %3 = OpConstant %2 1
 %4 = OpConstant %2 2
@@ -226,8 +226,8 @@
 %10 = OpTypeVoid
 %9 = OpTypeFunction %10
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"()");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpReturn
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()), R"()");
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpReturn
 )");
 
     Validate(b);
@@ -239,12 +239,12 @@
     spirv::Builder& b = Build();
 
     EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
-    EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
+    EXPECT_EQ(DumpInstructions(b.Module().Debug()), R"(OpName %1 "var"
 )");
-    EXPECT_EQ(DumpInstructions(b.annots()), R"(OpDecorate %1 Binding 2
+    EXPECT_EQ(DumpInstructions(b.Module().Annots()), R"(OpDecorate %1 Binding 2
 OpDecorate %1 DescriptorSet 3
 )");
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeSampler
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeSampler
 %2 = OpTypePointer UniformConstant %3
 %1 = OpVariable %2 UniformConstant
 )");
@@ -324,7 +324,7 @@
 
     ASSERT_TRUE(b.Build());
 
-    EXPECT_EQ(DumpInstructions(b.annots()), R"(OpDecorate %3 Block
+    EXPECT_EQ(DumpInstructions(b.Module().Annots()), R"(OpDecorate %3 Block
 OpMemberDecorate %3 0 Offset 0
 OpMemberDecorate %4 0 Offset 0
 OpMemberDecorate %4 1 Offset 4
@@ -332,7 +332,7 @@
 OpDecorate %1 Binding 0
 OpDecorate %1 DescriptorSet 0
 )");
-    EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %3 "b_block"
+    EXPECT_EQ(DumpInstructions(b.Module().Debug()), R"(OpName %3 "b_block"
 OpMemberName %3 0 "inner"
 OpName %4 "A"
 OpMemberName %4 0 "a"
@@ -340,7 +340,7 @@
 OpName %1 "b"
 OpName %8 "unused_entry_point"
 )");
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeInt 32 1
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%5 = OpTypeInt 32 1
 %4 = OpTypeStruct %5 %5
 %3 = OpTypeStruct %4
 %2 = OpTypePointer StorageBuffer %3
@@ -366,21 +366,21 @@
 
     ASSERT_TRUE(b.Build());
 
-    EXPECT_EQ(DumpInstructions(b.annots()), R"(OpDecorate %3 Block
+    EXPECT_EQ(DumpInstructions(b.Module().Annots()), R"(OpDecorate %3 Block
 OpMemberDecorate %3 0 Offset 0
 OpMemberDecorate %4 0 Offset 0
 OpDecorate %1 NonWritable
 OpDecorate %1 Binding 0
 OpDecorate %1 DescriptorSet 0
 )");
-    EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %3 "b_block"
+    EXPECT_EQ(DumpInstructions(b.Module().Debug()), R"(OpName %3 "b_block"
 OpMemberName %3 0 "inner"
 OpName %4 "A"
 OpMemberName %4 0 "a"
 OpName %1 "b"
 OpName %8 "unused_entry_point"
 )");
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeInt 32 1
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%5 = OpTypeInt 32 1
 %4 = OpTypeStruct %5
 %3 = OpTypeStruct %4
 %2 = OpTypePointer StorageBuffer %3
@@ -406,21 +406,21 @@
 
     ASSERT_TRUE(b.Build());
 
-    EXPECT_EQ(DumpInstructions(b.annots()), R"(OpDecorate %3 Block
+    EXPECT_EQ(DumpInstructions(b.Module().Annots()), R"(OpDecorate %3 Block
 OpMemberDecorate %3 0 Offset 0
 OpMemberDecorate %4 0 Offset 0
 OpDecorate %1 NonWritable
 OpDecorate %1 Binding 0
 OpDecorate %1 DescriptorSet 0
 )");
-    EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %3 "b_block"
+    EXPECT_EQ(DumpInstructions(b.Module().Debug()), R"(OpName %3 "b_block"
 OpMemberName %3 0 "inner"
 OpName %4 "A"
 OpMemberName %4 0 "a"
 OpName %1 "b"
 OpName %8 "unused_entry_point"
 )");
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeInt 32 1
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%5 = OpTypeInt 32 1
 %4 = OpTypeStruct %5
 %3 = OpTypeStruct %4
 %2 = OpTypePointer StorageBuffer %3
@@ -447,7 +447,7 @@
 
     ASSERT_TRUE(b.Build());
 
-    EXPECT_EQ(DumpInstructions(b.annots()),
+    EXPECT_EQ(DumpInstructions(b.Module().Annots()),
               R"(OpDecorate %3 Block
 OpMemberDecorate %3 0 Offset 0
 OpMemberDecorate %4 0 Offset 0
@@ -457,7 +457,7 @@
 OpDecorate %6 DescriptorSet 1
 OpDecorate %6 Binding 0
 )");
-    EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %3 "b_block"
+    EXPECT_EQ(DumpInstructions(b.Module().Debug()), R"(OpName %3 "b_block"
 OpMemberName %3 0 "inner"
 OpName %4 "A"
 OpMemberName %4 0 "a"
@@ -465,7 +465,7 @@
 OpName %6 "c"
 OpName %9 "unused_entry_point"
 )");
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeInt 32 1
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%5 = OpTypeInt 32 1
 %4 = OpTypeStruct %5
 %3 = OpTypeStruct %4
 %2 = OpTypePointer StorageBuffer %3
@@ -488,11 +488,11 @@
 
     EXPECT_TRUE(b.GenerateGlobalVariable(var_a)) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.annots()), R"(OpDecorate %1 NonReadable
+    EXPECT_EQ(DumpInstructions(b.Module().Annots()), R"(OpDecorate %1 NonReadable
 OpDecorate %1 Binding 0
 OpDecorate %1 DescriptorSet 0
 )");
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeInt 32 0
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeInt 32 0
 %3 = OpTypeImage %4 2D 0 0 0 2 R32ui
 %2 = OpTypePointer UniformConstant %3
 %1 = OpVariable %2 UniformConstant
@@ -523,7 +523,7 @@
     EXPECT_TRUE(b->GenerateGlobalVariable(var_struct)) << b->error();
     ASSERT_FALSE(b->has_error()) << b->error();
 
-    EXPECT_EQ(DumpInstructions(b->types()), R"(%3 = OpTypeInt 32 1
+    EXPECT_EQ(DumpInstructions(b->Module().Types()), R"(%3 = OpTypeInt 32 1
 %2 = OpTypePointer Workgroup %3
 %4 = OpConstantNull %3
 %1 = OpVariable %2 Workgroup %4
diff --git a/src/tint/writer/spirv/builder_ident_expression_test.cc b/src/tint/writer/spirv/builder_ident_expression_test.cc
index 7c56ba1..110619e 100644
--- a/src/tint/writer/spirv/builder_ident_expression_test.cc
+++ b/src/tint/writer/spirv/builder_ident_expression_test.cc
@@ -35,7 +35,7 @@
     EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
     ASSERT_FALSE(b.has_error()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"()");
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"()");
 
     EXPECT_EQ(b.GenerateIdentifierExpression(expr), 0u);
 }
@@ -48,11 +48,11 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
-    EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
+    EXPECT_EQ(DumpInstructions(b.Module().Debug()), R"(OpName %1 "var"
 )");
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 32
 %2 = OpTypePointer Private %3
 %4 = OpConstantNull %3
 %1 = OpVariable %2 Private %4
@@ -74,7 +74,7 @@
     EXPECT_TRUE(b.GenerateFunctionVariable(v)) << b.error();
     ASSERT_FALSE(b.has_error()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeVector %2 3
 %3 = OpConstant %2 1
 %4 = OpConstant %2 3
@@ -91,16 +91,16 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateFunctionVariable(v)) << b.error();
-    EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
+    EXPECT_EQ(DumpInstructions(b.Module().Debug()), R"(OpName %1 "var"
 )");
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 32
 %2 = OpTypePointer Function %3
 %4 = OpConstantNull %3
 )");
 
-    const auto& func = b.functions()[0];
+    const auto& func = b.CurrentFunction();
     EXPECT_EQ(DumpInstructions(func.variables()),
               R"(%1 = OpVariable %2 Function %4
 )");
@@ -115,16 +115,16 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
 
     EXPECT_EQ(b.GenerateBinaryExpression(expr->As<ast::BinaryExpression>()), 7u) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeInt 32 1
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeInt 32 1
 %2 = OpTypePointer Private %3
 %4 = OpConstantNull %3
 %1 = OpVariable %2 Private %4
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(%5 = OpLoad %3 %1
 %6 = OpLoad %3 %1
 %7 = OpIAdd %3 %5 %6
@@ -138,14 +138,14 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     ASSERT_TRUE(b.GenerateFunctionVariable(let)) << b.error();
 
     EXPECT_EQ(b.GenerateBinaryExpression(expr->As<ast::BinaryExpression>()), 3u) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 1
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeInt 32 1
 %2 = OpConstant %1 2
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(%3 = OpIAdd %1 %2 %2
 )");
 }
diff --git a/src/tint/writer/spirv/builder_if_test.cc b/src/tint/writer/spirv/builder_if_test.cc
index 031ed68..52ef0b6 100644
--- a/src/tint/writer/spirv/builder_if_test.cc
+++ b/src/tint/writer/spirv/builder_if_test.cc
@@ -30,13 +30,13 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
 
     EXPECT_TRUE(b.GenerateIfStatement(expr)) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeBool
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeBool
 %2 = OpConstantTrue %1
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpSelectionMerge %3 None
 OpBranchConditional %2 %4 %3
 %4 = OpLabel
@@ -75,11 +75,11 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
 
     EXPECT_TRUE(b.GenerateIfStatement(expr)) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeInt 32 1
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeInt 32 1
 %2 = OpTypePointer Private %3
 %4 = OpConstantNull %3
 %1 = OpVariable %2 Private %4
@@ -87,7 +87,7 @@
 %6 = OpConstantTrue %5
 %9 = OpConstant %3 2
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpSelectionMerge %7 None
 OpBranchConditional %6 %8 %7
 %8 = OpLabel
@@ -113,11 +113,11 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
 
     EXPECT_TRUE(b.GenerateIfStatement(expr)) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeInt 32 1
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeInt 32 1
 %2 = OpTypePointer Private %3
 %4 = OpConstantNull %3
 %1 = OpVariable %2 Private %4
@@ -126,7 +126,7 @@
 %10 = OpConstant %3 2
 %11 = OpConstant %3 3
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpSelectionMerge %7 None
 OpBranchConditional %6 %8 %9
 %8 = OpLabel
@@ -155,11 +155,11 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
 
     EXPECT_TRUE(b.GenerateIfStatement(expr)) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeInt 32 1
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeInt 32 1
 %2 = OpTypePointer Private %3
 %4 = OpConstantNull %3
 %1 = OpVariable %2 Private %4
@@ -168,7 +168,7 @@
 %10 = OpConstant %3 2
 %13 = OpConstant %3 3
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpSelectionMerge %7 None
 OpBranchConditional %6 %8 %9
 %8 = OpLabel
@@ -211,11 +211,11 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
 
     EXPECT_TRUE(b.GenerateIfStatement(expr)) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeInt 32 1
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeInt 32 1
 %2 = OpTypePointer Private %3
 %4 = OpConstantNull %3
 %1 = OpVariable %2 Private %4
@@ -227,7 +227,7 @@
 %19 = OpConstant %3 4
 %20 = OpConstant %3 5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpSelectionMerge %7 None
 OpBranchConditional %6 %8 %9
 %8 = OpLabel
@@ -274,13 +274,13 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
 
     EXPECT_TRUE(b.GenerateLoopStatement(expr)) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeBool
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%5 = OpTypeBool
 %6 = OpConstantTrue %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpBranch %1
 %1 = OpLabel
 OpLoopMerge %2 %3 None
@@ -316,13 +316,13 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
 
     EXPECT_TRUE(b.GenerateLoopStatement(expr)) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeBool
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%5 = OpTypeBool
 %6 = OpConstantTrue %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpBranch %1
 %1 = OpLabel
 OpLoopMerge %2 %3 None
@@ -358,13 +358,13 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
 
     EXPECT_TRUE(b.GenerateLoopStatement(expr)) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeBool
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%5 = OpTypeBool
 %6 = OpConstantTrue %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpBranch %1
 %1 = OpLabel
 OpLoopMerge %2 %3 None
@@ -403,13 +403,13 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
 
     EXPECT_TRUE(b.GenerateLoopStatement(expr)) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeBool
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%5 = OpTypeBool
 %6 = OpConstantTrue %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpBranch %1
 %1 = OpLabel
 OpLoopMerge %2 %3 None
@@ -442,12 +442,12 @@
     spirv::Builder& b = Build();
 
     EXPECT_TRUE(b.GenerateFunction(fn)) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %5 = OpTypeBool
 %6 = OpConstantTrue %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
               R"(OpSelectionMerge %7 None
 OpBranchConditional %6 %8 %7
 %8 = OpLabel
@@ -472,12 +472,12 @@
     spirv::Builder& b = Build();
 
     EXPECT_TRUE(b.GenerateFunction(fn)) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeBool
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeBool
 %1 = OpTypeFunction %2
 %5 = OpConstantTrue %2
 %8 = OpConstantNull %2
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
               R"(OpSelectionMerge %6 None
 OpBranchConditional %5 %7 %6
 %7 = OpLabel
@@ -504,12 +504,12 @@
     spirv::Builder& b = Build();
 
     EXPECT_TRUE(b.GenerateFunction(fn)) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeBool
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeBool
 %1 = OpTypeFunction %2
 %5 = OpConstantTrue %2
 %9 = OpConstantNull %2
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
               R"(OpSelectionMerge %6 None
 OpBranchConditional %5 %7 %8
 %7 = OpLabel
@@ -542,12 +542,12 @@
     spirv::Builder& b = Build();
 
     EXPECT_TRUE(b.GenerateFunction(fn)) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeBool
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeBool
 %1 = OpTypeFunction %2
 %5 = OpConstantTrue %2
 %8 = OpConstantNull %2
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
               R"(OpSelectionMerge %6 None
 OpBranchConditional %5 %7 %6
 %7 = OpLabel
@@ -572,14 +572,14 @@
 
     ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
     EXPECT_TRUE(b.GenerateFunction(fn)) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeBool
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeBool
 %2 = OpTypePointer Private %3
 %4 = OpConstantNull %3
 %1 = OpVariable %2 Private %4
 %6 = OpTypeVoid
 %5 = OpTypeFunction %6
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
               R"(%9 = OpLoad %3 %1
 OpSelectionMerge %10 None
 OpBranchConditional %9 %11 %10
@@ -603,13 +603,13 @@
     spirv::Builder& b = Build();
 
     EXPECT_TRUE(b.GenerateFunction(fn)) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %5 = OpTypeBool
 %6 = OpConstantNull %5
 %10 = OpConstantTrue %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
               R"(OpSelectionMerge %7 None
 OpBranchConditional %6 %8 %9
 %8 = OpLabel
@@ -644,13 +644,13 @@
     spirv::Builder& b = Build();
 
     EXPECT_TRUE(b.GenerateFunction(fn)) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
 %9 = OpTypeBool
 %10 = OpConstantNull %9
 %14 = OpConstantTrue %9
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
               R"(OpBranch %5
 %5 = OpLabel
 OpLoopMerge %6 %7 None
diff --git a/src/tint/writer/spirv/builder_literal_test.cc b/src/tint/writer/spirv/builder_literal_test.cc
index 3a9ec29..eea1d8c 100644
--- a/src/tint/writer/spirv/builder_literal_test.cc
+++ b/src/tint/writer/spirv/builder_literal_test.cc
@@ -31,7 +31,7 @@
     ASSERT_FALSE(b.has_error()) << b.error();
     EXPECT_EQ(2u, id);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeBool
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeBool
 %2 = OpConstantTrue %1
 )");
 }
@@ -46,7 +46,7 @@
     ASSERT_FALSE(b.has_error()) << b.error();
     EXPECT_EQ(2u, id);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeBool
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeBool
 %2 = OpConstantFalse %1
 )");
 }
@@ -65,7 +65,7 @@
     ASSERT_NE(b.GenerateLiteralIfNeeded(b_true), 0u);
     ASSERT_FALSE(b.has_error()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeBool
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeBool
 %2 = OpConstantTrue %1
 %3 = OpConstantFalse %1
 )");
@@ -80,7 +80,7 @@
     ASSERT_FALSE(b.has_error()) << b.error();
     EXPECT_EQ(2u, id);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 1
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeInt 32 1
 %2 = OpConstant %1 -23
 )");
 }
@@ -96,7 +96,7 @@
     ASSERT_NE(b.GenerateLiteralIfNeeded(i2), 0u);
     ASSERT_FALSE(b.has_error()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 1
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeInt 32 1
 %2 = OpConstant %1 -23
 )");
 }
@@ -111,7 +111,7 @@
     ASSERT_FALSE(b.has_error()) << b.error();
     EXPECT_EQ(2u, id);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 0
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeInt 32 0
 %2 = OpConstant %1 23
 )");
 }
@@ -127,7 +127,7 @@
     ASSERT_NE(b.GenerateLiteralIfNeeded(i2), 0u);
     ASSERT_FALSE(b.has_error()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 0
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeInt 32 0
 %2 = OpConstant %1 23
 )");
 }
@@ -142,7 +142,7 @@
     ASSERT_FALSE(b.has_error()) << b.error();
     EXPECT_EQ(2u, id);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 32
 %2 = OpConstant %1 23.2450008
 )");
 }
@@ -158,7 +158,7 @@
     ASSERT_NE(b.GenerateLiteralIfNeeded(i2), 0u);
     ASSERT_FALSE(b.has_error()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 32
 %2 = OpConstant %1 23.2450008
 )");
 }
@@ -175,7 +175,7 @@
     ASSERT_FALSE(b.has_error()) << b.error();
     EXPECT_EQ(2u, id);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 16
 %2 = OpConstant %1 0x1.73cp+4
 )");
 }
@@ -193,7 +193,7 @@
     ASSERT_NE(b.GenerateLiteralIfNeeded(i2), 0u);
     ASSERT_FALSE(b.has_error()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 16
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 16
 %2 = OpConstant %1 0x1.73cp+4
 )");
 }
diff --git a/src/tint/writer/spirv/builder_loop_test.cc b/src/tint/writer/spirv/builder_loop_test.cc
index 5fc15b8..addb283 100644
--- a/src/tint/writer/spirv/builder_loop_test.cc
+++ b/src/tint/writer/spirv/builder_loop_test.cc
@@ -32,10 +32,10 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
 
     EXPECT_TRUE(b.GenerateLoopStatement(loop)) << b.error();
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpBranch %1
 %1 = OpLabel
 OpLoopMerge %2 %3 None
@@ -63,17 +63,17 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
 
     EXPECT_TRUE(b.GenerateLoopStatement(loop)) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeInt 32 1
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeInt 32 1
 %2 = OpTypePointer Private %3
 %4 = OpConstantNull %3
 %1 = OpVariable %2 Private %4
 %9 = OpConstant %3 2
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpBranch %5
 %5 = OpLabel
 OpLoopMerge %6 %7 None
@@ -106,18 +106,18 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
 
     EXPECT_TRUE(b.GenerateLoopStatement(loop)) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeInt 32 1
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeInt 32 1
 %2 = OpTypePointer Private %3
 %4 = OpConstantNull %3
 %1 = OpVariable %2 Private %4
 %9 = OpConstant %3 2
 %10 = OpConstant %3 3
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpBranch %5
 %5 = OpLabel
 OpLoopMerge %6 %7 None
@@ -150,15 +150,15 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateLoopStatement(loop)) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%7 = OpTypeInt 32 1
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%7 = OpTypeInt 32 1
 %6 = OpTypePointer Function %7
 %8 = OpConstantNull %7
 %9 = OpConstant %7 3
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpBranch %1
 %1 = OpLabel
 OpLoopMerge %2 %3 None
@@ -184,10 +184,10 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
 
     EXPECT_TRUE(b.GenerateLoopStatement(loop)) << b.error();
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpBranch %1
 %1 = OpLabel
 OpLoopMerge %2 %3 None
@@ -215,10 +215,10 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
 
     EXPECT_TRUE(b.GenerateLoopStatement(loop)) << b.error();
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpBranch %1
 %1 = OpLabel
 OpLoopMerge %2 %3 None
@@ -244,13 +244,13 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
 
     EXPECT_TRUE(b.GenerateLoopStatement(loop)) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeBool
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%5 = OpTypeBool
 %6 = OpConstantTrue %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpBranch %1
 %1 = OpLabel
 OpLoopMerge %2 %3 None
@@ -275,13 +275,13 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
 
     EXPECT_TRUE(b.GenerateLoopStatement(loop)) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeBool
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%5 = OpTypeBool
 %6 = OpConstantNull %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpBranch %1
 %1 = OpLabel
 OpLoopMerge %2 %3 None
@@ -309,15 +309,15 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
 
     EXPECT_TRUE(b.GenerateLoopStatement(loop)) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeBool
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%5 = OpTypeBool
 %6 = OpConstantTrue %5
 %8 = OpTypePointer Function %5
 %9 = OpConstantNull %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpBranch %1
 %1 = OpLabel
 OpLoopMerge %2 %3 None
@@ -355,13 +355,13 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
 
     EXPECT_TRUE(b.GenerateLoopStatement(outer_loop)) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%9 = OpTypeBool
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%9 = OpTypeBool
 %10 = OpConstantTrue %9
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpBranch %1
 %1 = OpLabel
 OpLoopMerge %2 %3 None
diff --git a/src/tint/writer/spirv/builder_return_test.cc b/src/tint/writer/spirv/builder_return_test.cc
index 825529e..897211c 100644
--- a/src/tint/writer/spirv/builder_return_test.cc
+++ b/src/tint/writer/spirv/builder_return_test.cc
@@ -28,11 +28,11 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateReturnStatement(ret));
     ASSERT_FALSE(b.has_error()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpReturn
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"(OpReturn
 )");
 }
 
@@ -44,17 +44,17 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateReturnStatement(ret));
     ASSERT_FALSE(b.has_error()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeVector %2 3
 %3 = OpConstant %2 1
 %4 = OpConstant %2 3
 %5 = OpConstantComposite %1 %3 %3 %4
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpReturnValue %5
 )");
 }
@@ -67,19 +67,19 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
     EXPECT_TRUE(b.GenerateReturnStatement(ret)) << b.error();
     ASSERT_FALSE(b.has_error()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 32
 %2 = OpTypePointer Function %3
 %4 = OpConstantNull %3
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().variables()),
               R"(%1 = OpVariable %2 Function %4
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(%5 = OpLoad %3 %1
 OpReturnValue %5
 )");
diff --git a/src/tint/writer/spirv/builder_switch_test.cc b/src/tint/writer/spirv/builder_switch_test.cc
index 7e0bd18..e950c41 100644
--- a/src/tint/writer/spirv/builder_switch_test.cc
+++ b/src/tint/writer/spirv/builder_switch_test.cc
@@ -32,13 +32,13 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
 
     EXPECT_TRUE(b.GenerateSwitchStatement(expr)) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 1
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeInt 32 1
 %3 = OpConstant %2 1
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(OpSelectionMerge %1 None
 OpSwitch %3 %4
 %4 = OpLabel
diff --git a/src/tint/writer/spirv/builder_test.cc b/src/tint/writer/spirv/builder_test.cc
index 1c79988..718f246 100644
--- a/src/tint/writer/spirv/builder_test.cc
+++ b/src/tint/writer/spirv/builder_test.cc
@@ -12,7 +12,6 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/tint/writer/spirv/spv_dump.h"
 #include "src/tint/writer/spirv/test_helper.h"
 
 namespace tint::writer::spirv {
@@ -38,33 +37,5 @@
               R"(12:34 error: SPIR-V backend does not support extension 'undefined')");
 }
 
-TEST_F(BuilderTest, TracksIdBounds) {
-    spirv::Builder& b = Build();
-
-    for (size_t i = 0; i < 5; i++) {
-        EXPECT_EQ(b.next_id(), i + 1);
-    }
-
-    EXPECT_EQ(6u, b.id_bound());
-}
-
-TEST_F(BuilderTest, Capabilities_Dedup) {
-    spirv::Builder& b = Build();
-
-    b.push_capability(SpvCapabilityShader);
-    b.push_capability(SpvCapabilityShader);
-    b.push_capability(SpvCapabilityShader);
-
-    EXPECT_EQ(DumpInstructions(b.capabilities()), "OpCapability Shader\n");
-}
-
-TEST_F(BuilderTest, DeclareExtension) {
-    spirv::Builder& b = Build();
-
-    b.push_extension("SPV_KHR_integer_dot_product");
-
-    EXPECT_EQ(DumpInstructions(b.extensions()), "OpExtension \"SPV_KHR_integer_dot_product\"\n");
-}
-
 }  // namespace
 }  // namespace tint::writer::spirv
diff --git a/src/tint/writer/spirv/builder_type_test.cc b/src/tint/writer/spirv/builder_type_test.cc
index 89ba34e..1edb4a8 100644
--- a/src/tint/writer/spirv/builder_type_test.cc
+++ b/src/tint/writer/spirv/builder_type_test.cc
@@ -39,7 +39,7 @@
     ASSERT_FALSE(b.has_error()) << b.error();
     EXPECT_EQ(1u, id);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 1
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeInt 32 1
 %1 = OpTypeRuntimeArray %2
 )");
 }
@@ -57,7 +57,7 @@
     EXPECT_EQ(b.GenerateTypeIfNeeded(program->TypeOf(type)), 1u);
     ASSERT_FALSE(b.has_error()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 1
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeInt 32 1
 %1 = OpTypeRuntimeArray %2
 )");
 }
@@ -72,7 +72,7 @@
     ASSERT_FALSE(b.has_error()) << b.error();
     EXPECT_EQ(1u, id);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 1
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeInt 32 1
 %3 = OpTypeInt 32 0
 %4 = OpConstant %3 4
 %1 = OpTypeArray %2 %4
@@ -89,10 +89,10 @@
     ASSERT_FALSE(b.has_error()) << b.error();
     EXPECT_EQ(1u, id);
 
-    EXPECT_EQ(DumpInstructions(b.annots()), R"(OpDecorate %1 ArrayStride 16
+    EXPECT_EQ(DumpInstructions(b.Module().Annots()), R"(OpDecorate %1 ArrayStride 16
 )");
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 1
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeInt 32 1
 %3 = OpTypeInt 32 0
 %4 = OpConstant %3 4
 %1 = OpTypeArray %2 %4
@@ -109,7 +109,7 @@
     EXPECT_EQ(b.GenerateTypeIfNeeded(program->TypeOf(ty)), 1u);
     ASSERT_FALSE(b.has_error()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 1
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeInt 32 1
 %3 = OpTypeInt 32 0
 %4 = OpConstant %3 4
 %1 = OpTypeArray %2 %4
@@ -125,8 +125,8 @@
     ASSERT_FALSE(b.has_error()) << b.error();
     EXPECT_EQ(id, 1u);
 
-    ASSERT_EQ(b.types().size(), 1u);
-    EXPECT_EQ(DumpInstruction(b.types()[0]), R"(%1 = OpTypeBool
+    ASSERT_EQ(b.Module().Types().size(), 1u);
+    EXPECT_EQ(DumpInstruction(b.Module().Types()[0]), R"(%1 = OpTypeBool
 )");
 }
 
@@ -153,8 +153,8 @@
     ASSERT_FALSE(b.has_error()) << b.error();
     EXPECT_EQ(id, 1u);
 
-    ASSERT_EQ(b.types().size(), 1u);
-    EXPECT_EQ(DumpInstruction(b.types()[0]), R"(%1 = OpTypeFloat 32
+    ASSERT_EQ(b.Module().Types().size(), 1u);
+    EXPECT_EQ(DumpInstruction(b.Module().Types()[0]), R"(%1 = OpTypeFloat 32
 )");
 }
 
@@ -181,8 +181,8 @@
     ASSERT_FALSE(b.has_error()) << b.error();
     EXPECT_EQ(id, 1u);
 
-    ASSERT_EQ(b.types().size(), 1u);
-    EXPECT_EQ(DumpInstruction(b.types()[0]), R"(%1 = OpTypeFloat 16
+    ASSERT_EQ(b.Module().Types().size(), 1u);
+    EXPECT_EQ(DumpInstruction(b.Module().Types()[0]), R"(%1 = OpTypeFloat 16
 )");
 }
 
@@ -209,8 +209,8 @@
     ASSERT_FALSE(b.has_error()) << b.error();
     EXPECT_EQ(id, 1u);
 
-    ASSERT_EQ(b.types().size(), 1u);
-    EXPECT_EQ(DumpInstruction(b.types()[0]), R"(%1 = OpTypeInt 32 1
+    ASSERT_EQ(b.Module().Types().size(), 1u);
+    EXPECT_EQ(DumpInstruction(b.Module().Types()[0]), R"(%1 = OpTypeInt 32 1
 )");
 }
 
@@ -239,8 +239,8 @@
     ASSERT_FALSE(b.has_error()) << b.error();
     EXPECT_EQ(id, 1u);
 
-    EXPECT_EQ(b.types().size(), 3u);
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
+    EXPECT_EQ(b.Module().Types().size(), 3u);
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 32
 %2 = OpTypeVector %3 3
 %1 = OpTypeMatrix %2 2
 )");
@@ -272,8 +272,8 @@
     ASSERT_FALSE(b.has_error()) << b.error();
     EXPECT_EQ(id, 1u);
 
-    EXPECT_EQ(b.types().size(), 3u);
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 16
+    EXPECT_EQ(b.Module().Types().size(), 3u);
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 16
 %2 = OpTypeVector %3 3
 %1 = OpTypeMatrix %2 2
 )");
@@ -305,7 +305,7 @@
     ASSERT_FALSE(b.has_error()) << b.error();
     EXPECT_EQ(1u, id);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 1
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeInt 32 1
 %1 = OpTypePointer Output %2
 )");
 }
@@ -332,11 +332,11 @@
     ASSERT_FALSE(b.has_error()) << b.error();
     EXPECT_EQ(id, 1u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %3 = OpTypeFloat 16
 %1 = OpTypeStruct %2 %3
 )");
-    EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "my_struct"
+    EXPECT_EQ(DumpInstructions(b.Module().Debug()), R"(OpName %1 "my_struct"
 OpMemberName %1 0 "a"
 OpMemberName %1 1 "b"
 )");
@@ -358,17 +358,17 @@
     ASSERT_FALSE(b.has_error()) << b.error();
     EXPECT_EQ(id, 1u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %3 = OpTypeFloat 16
 %1 = OpTypeStruct %2 %2 %3 %3
 )");
-    EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "S"
+    EXPECT_EQ(DumpInstructions(b.Module().Debug()), R"(OpName %1 "S"
 OpMemberName %1 0 "a"
 OpMemberName %1 1 "b"
 OpMemberName %1 2 "c"
 OpMemberName %1 3 "d"
 )");
-    EXPECT_EQ(DumpInstructions(b.annots()), R"(OpMemberDecorate %1 0 Offset 0
+    EXPECT_EQ(DumpInstructions(b.Module().Annots()), R"(OpMemberDecorate %1 0 Offset 0
 OpMemberDecorate %1 1 Offset 8
 OpMemberDecorate %1 2 Offset 16
 OpMemberDecorate %1 3 Offset 18
@@ -394,7 +394,7 @@
     ASSERT_FALSE(b.has_error()) << b.error();
     EXPECT_EQ(id, 1u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeFloat 32
 %3 = OpTypeVector %4 2
 %2 = OpTypeMatrix %3 2
 %6 = OpTypeVector %4 3
@@ -410,7 +410,7 @@
 %14 = OpTypeMatrix %15 4
 %1 = OpTypeStruct %2 %5 %7 %9 %12 %14
 )");
-    EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "S"
+    EXPECT_EQ(DumpInstructions(b.Module().Debug()), R"(OpName %1 "S"
 OpMemberName %1 0 "mat2x2_f32"
 OpMemberName %1 1 "mat2x3_f32"
 OpMemberName %1 2 "mat4x4_f32"
@@ -418,7 +418,7 @@
 OpMemberName %1 4 "mat2x3_f16"
 OpMemberName %1 5 "mat4x4_f16"
 )");
-    EXPECT_EQ(DumpInstructions(b.annots()), R"(OpMemberDecorate %1 0 Offset 0
+    EXPECT_EQ(DumpInstructions(b.Module().Annots()), R"(OpMemberDecorate %1 0 Offset 0
 OpMemberDecorate %1 0 ColMajor
 OpMemberDecorate %1 0 MatrixStride 8
 OpMemberDecorate %1 1 Offset 64
@@ -465,7 +465,7 @@
     ASSERT_FALSE(b.has_error()) << b.error();
     EXPECT_EQ(id, 1u);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%5 = OpTypeFloat 32
 %4 = OpTypeVector %5 2
 %3 = OpTypeMatrix %4 2
 %6 = OpTypeInt 32 0
@@ -489,14 +489,14 @@
 %21 = OpTypeRuntimeArray %22
 %1 = OpTypeStruct %2 %8 %12 %17 %21
 )");
-    EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "S"
+    EXPECT_EQ(DumpInstructions(b.Module().Debug()), R"(OpName %1 "S"
 OpMemberName %1 0 "arr_mat2x2_f32"
 OpMemberName %1 1 "arr_mat2x2_f16"
 OpMemberName %1 2 "arr_arr_mat2x3_f32"
 OpMemberName %1 3 "arr_arr_mat2x3_f16"
 OpMemberName %1 4 "rtarr_mat4x4"
 )");
-    EXPECT_EQ(DumpInstructions(b.annots()), R"(OpMemberDecorate %1 0 Offset 0
+    EXPECT_EQ(DumpInstructions(b.Module().Annots()), R"(OpMemberDecorate %1 0 Offset 0
 OpMemberDecorate %1 0 ColMajor
 OpMemberDecorate %1 0 MatrixStride 8
 OpDecorate %2 ArrayStride 16
@@ -530,8 +530,8 @@
     ASSERT_FALSE(b.has_error()) << b.error();
     EXPECT_EQ(id, 1u);
 
-    ASSERT_EQ(b.types().size(), 1u);
-    EXPECT_EQ(DumpInstruction(b.types()[0]), R"(%1 = OpTypeInt 32 0
+    ASSERT_EQ(b.Module().Types().size(), 1u);
+    EXPECT_EQ(DumpInstruction(b.Module().Types()[0]), R"(%1 = OpTypeInt 32 0
 )");
 }
 
@@ -558,8 +558,8 @@
     ASSERT_FALSE(b.has_error()) << b.error();
     EXPECT_EQ(id, 1u);
 
-    EXPECT_EQ(b.types().size(), 2u);
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(b.Module().Types().size(), 2u);
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeVector %2 3
 )");
 }
@@ -587,8 +587,8 @@
     ASSERT_FALSE(b.has_error()) << b.error();
     EXPECT_EQ(id, 1u);
 
-    ASSERT_EQ(b.types().size(), 1u);
-    EXPECT_EQ(DumpInstruction(b.types()[0]), R"(%1 = OpTypeVoid
+    ASSERT_EQ(b.Module().Types().size(), 1u);
+    EXPECT_EQ(DumpInstruction(b.Module().Types()[0]), R"(%1 = OpTypeVoid
 )");
 }
 
@@ -646,7 +646,7 @@
     ASSERT_FALSE(b.has_error()) << b.error();
     EXPECT_EQ(1u, id_two_d);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeImage %2 2D 0 0 0 1 Unknown
 )");
 }
@@ -660,7 +660,7 @@
     ASSERT_FALSE(b.has_error()) << b.error();
     EXPECT_EQ(1u, id_two_d_array);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeImage %2 2D 0 1 0 1 Unknown
 )");
 }
@@ -674,10 +674,10 @@
     ASSERT_FALSE(b.has_error()) << b.error();
     EXPECT_EQ(1u, id_cube);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeImage %2 Cube 0 0 0 1 Unknown
 )");
-    EXPECT_EQ(DumpInstructions(b.capabilities()), "");
+    EXPECT_EQ(DumpInstructions(b.Module().Capabilities()), "");
 }
 
 TEST_F(BuilderTest_Type, DepthTexture_Generate_CubeArray) {
@@ -689,10 +689,10 @@
     ASSERT_FALSE(b.has_error()) << b.error();
     EXPECT_EQ(1u, id_cube_array);
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeImage %2 Cube 0 1 0 1 Unknown
 )");
-    EXPECT_EQ(DumpInstructions(b.capabilities()),
+    EXPECT_EQ(DumpInstructions(b.Module().Capabilities()),
               R"(OpCapability SampledCubeArray
 )");
 }
@@ -705,7 +705,7 @@
 
     EXPECT_EQ(1u, b.GenerateTypeIfNeeded(ms));
     ASSERT_FALSE(b.has_error()) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 1
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeInt 32 1
 %1 = OpTypeImage %2 2D 0 0 1 1 Unknown
 )");
 }
@@ -718,7 +718,7 @@
 
     EXPECT_EQ(b.GenerateTypeIfNeeded(ms), 1u);
     ASSERT_FALSE(b.has_error()) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()),
+    EXPECT_EQ(DumpInstructions(b.Module().Types()),
               R"(%2 = OpTypeInt 32 0
 %1 = OpTypeImage %2 2D 0 0 1 1 Unknown
 )");
@@ -732,7 +732,7 @@
 
     EXPECT_EQ(b.GenerateTypeIfNeeded(ms), 1u);
     ASSERT_FALSE(b.has_error()) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()),
+    EXPECT_EQ(DumpInstructions(b.Module().Types()),
               R"(%2 = OpTypeFloat 32
 %1 = OpTypeImage %2 2D 0 0 1 1 Unknown
 )");
@@ -745,12 +745,12 @@
 
     EXPECT_EQ(b.GenerateTypeIfNeeded(s), 1u);
     ASSERT_FALSE(b.has_error()) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()),
+    EXPECT_EQ(DumpInstructions(b.Module().Types()),
               R"(%2 = OpTypeInt 32 1
 %1 = OpTypeImage %2 1D 0 0 0 1 Unknown
 )");
 
-    EXPECT_EQ(DumpInstructions(b.capabilities()),
+    EXPECT_EQ(DumpInstructions(b.Module().Capabilities()),
               R"(OpCapability Sampled1D
 )");
 }
@@ -763,12 +763,12 @@
 
     EXPECT_EQ(b.GenerateTypeIfNeeded(s), 1u);
     ASSERT_FALSE(b.has_error()) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()),
+    EXPECT_EQ(DumpInstructions(b.Module().Types()),
               R"(%2 = OpTypeInt 32 0
 %1 = OpTypeImage %2 1D 0 0 0 1 Unknown
 )");
 
-    EXPECT_EQ(DumpInstructions(b.capabilities()),
+    EXPECT_EQ(DumpInstructions(b.Module().Capabilities()),
               R"(OpCapability Sampled1D
 )");
 }
@@ -781,12 +781,12 @@
 
     EXPECT_EQ(b.GenerateTypeIfNeeded(s), 1u);
     ASSERT_FALSE(b.has_error()) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()),
+    EXPECT_EQ(DumpInstructions(b.Module().Types()),
               R"(%2 = OpTypeFloat 32
 %1 = OpTypeImage %2 1D 0 0 0 1 Unknown
 )");
 
-    EXPECT_EQ(DumpInstructions(b.capabilities()),
+    EXPECT_EQ(DumpInstructions(b.Module().Capabilities()),
               R"(OpCapability Sampled1D
 )");
 }
@@ -799,7 +799,7 @@
 
     EXPECT_EQ(b.GenerateTypeIfNeeded(s), 1u);
     ASSERT_FALSE(b.has_error()) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()),
+    EXPECT_EQ(DumpInstructions(b.Module().Types()),
               R"(%2 = OpTypeFloat 32
 %1 = OpTypeImage %2 2D 0 0 0 1 Unknown
 )");
@@ -813,7 +813,7 @@
 
     EXPECT_EQ(b.GenerateTypeIfNeeded(s), 1u);
     ASSERT_FALSE(b.has_error()) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()),
+    EXPECT_EQ(DumpInstructions(b.Module().Types()),
               R"(%2 = OpTypeFloat 32
 %1 = OpTypeImage %2 2D 0 1 0 1 Unknown
 )");
@@ -827,7 +827,7 @@
 
     EXPECT_EQ(b.GenerateTypeIfNeeded(s), 1u);
     ASSERT_FALSE(b.has_error()) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()),
+    EXPECT_EQ(DumpInstructions(b.Module().Types()),
               R"(%2 = OpTypeFloat 32
 %1 = OpTypeImage %2 3D 0 0 0 1 Unknown
 )");
@@ -841,11 +841,11 @@
 
     EXPECT_EQ(b.GenerateTypeIfNeeded(s), 1u);
     ASSERT_FALSE(b.has_error()) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()),
+    EXPECT_EQ(DumpInstructions(b.Module().Types()),
               R"(%2 = OpTypeFloat 32
 %1 = OpTypeImage %2 Cube 0 0 0 1 Unknown
 )");
-    EXPECT_EQ(DumpInstructions(b.capabilities()), "");
+    EXPECT_EQ(DumpInstructions(b.Module().Capabilities()), "");
 }
 
 TEST_F(BuilderTest_Type, SampledTexture_Generate_CubeArray) {
@@ -856,11 +856,11 @@
 
     EXPECT_EQ(b.GenerateTypeIfNeeded(s), 1u);
     ASSERT_FALSE(b.has_error()) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()),
+    EXPECT_EQ(DumpInstructions(b.Module().Types()),
               R"(%2 = OpTypeFloat 32
 %1 = OpTypeImage %2 Cube 0 1 0 1 Unknown
 )");
-    EXPECT_EQ(DumpInstructions(b.capabilities()),
+    EXPECT_EQ(DumpInstructions(b.Module().Capabilities()),
               R"(OpCapability SampledCubeArray
 )");
 }
@@ -875,7 +875,7 @@
 
     EXPECT_EQ(b.GenerateTypeIfNeeded(program->TypeOf(ty)), 1u);
     ASSERT_FALSE(b.has_error()) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeImage %2 1D 0 0 0 2 R32f
 )");
 }
@@ -890,7 +890,7 @@
 
     EXPECT_EQ(b.GenerateTypeIfNeeded(program->TypeOf(ty)), 1u);
     ASSERT_FALSE(b.has_error()) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeImage %2 2D 0 0 0 2 R32f
 )");
 }
@@ -905,7 +905,7 @@
 
     EXPECT_EQ(b.GenerateTypeIfNeeded(program->TypeOf(ty)), 1u);
     ASSERT_FALSE(b.has_error()) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeImage %2 2D 0 1 0 2 R32f
 )");
 }
@@ -920,7 +920,7 @@
 
     EXPECT_EQ(b.GenerateTypeIfNeeded(program->TypeOf(ty)), 1u);
     ASSERT_FALSE(b.has_error()) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeImage %2 3D 0 0 0 2 R32f
 )");
 }
@@ -935,7 +935,7 @@
 
     EXPECT_EQ(b.GenerateTypeIfNeeded(program->TypeOf(ty)), 1u);
     ASSERT_FALSE(b.has_error()) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %1 = OpTypeImage %2 2D 0 0 0 2 R32f
 )");
 }
@@ -950,7 +950,7 @@
 
     EXPECT_EQ(b.GenerateTypeIfNeeded(program->TypeOf(ty)), 1u);
     ASSERT_FALSE(b.has_error()) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 1
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeInt 32 1
 %1 = OpTypeImage %2 2D 0 0 0 2 R32i
 )");
 }
@@ -965,7 +965,7 @@
 
     EXPECT_EQ(b.GenerateTypeIfNeeded(program->TypeOf(ty)), 1u);
     ASSERT_FALSE(b.has_error()) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 0
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeInt 32 0
 %1 = OpTypeImage %2 2D 0 0 0 2 R32ui
 )");
 }
@@ -977,7 +977,7 @@
 
     EXPECT_EQ(b.GenerateTypeIfNeeded(sampler), 1u);
     ASSERT_FALSE(b.has_error()) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), "%1 = OpTypeSampler\n");
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), "%1 = OpTypeSampler\n");
 }
 
 TEST_F(BuilderTest_Type, ComparisonSampler) {
@@ -987,7 +987,7 @@
 
     EXPECT_EQ(b.GenerateTypeIfNeeded(sampler), 1u);
     ASSERT_FALSE(b.has_error()) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), "%1 = OpTypeSampler\n");
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), "%1 = OpTypeSampler\n");
 }
 
 TEST_F(BuilderTest_Type, Dedup_Sampler_And_ComparisonSampler) {
@@ -1001,7 +1001,7 @@
     EXPECT_EQ(b.GenerateTypeIfNeeded(sampler), 1u);
 
     ASSERT_FALSE(b.has_error()) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), "%1 = OpTypeSampler\n");
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), "%1 = OpTypeSampler\n");
 }
 
 }  // namespace
diff --git a/src/tint/writer/spirv/builder_unary_op_expression_test.cc b/src/tint/writer/spirv/builder_unary_op_expression_test.cc
index e28eb78..79de457 100644
--- a/src/tint/writer/spirv/builder_unary_op_expression_test.cc
+++ b/src/tint/writer/spirv/builder_unary_op_expression_test.cc
@@ -28,12 +28,12 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateUnaryOpExpression(expr), 1u) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 1
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeInt 32 1
 %3 = OpConstant %2 1
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(%1 = OpSNegate %2 %3
 )");
 }
@@ -44,12 +44,12 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateUnaryOpExpression(expr), 1u) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
 %3 = OpConstant %2 1
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(%1 = OpFNegate %2 %3
 )");
 }
@@ -60,12 +60,12 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateUnaryOpExpression(expr), 1u) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 1
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeInt 32 1
 %3 = OpConstant %2 1
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(%1 = OpNot %2 %3
 )");
 }
@@ -76,12 +76,12 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_EQ(b.GenerateUnaryOpExpression(expr), 1u) << b.error();
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeBool
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeBool
 %3 = OpConstantNull %2
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(%1 = OpLogicalNot %2 %3
 )");
 }
@@ -94,20 +94,20 @@
 
     spirv::Builder& b = Build();
 
-    b.push_function(Function{});
+    b.PushFunctionForTesting();
     EXPECT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
     EXPECT_EQ(b.GenerateUnaryOpExpression(expr), 6u) << b.error();
     ASSERT_FALSE(b.has_error()) << b.error();
 
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
+    EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeFloat 32
 %3 = OpTypeVector %4 3
 %2 = OpTypePointer Function %3
 %5 = OpConstantNull %3
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().variables()),
               R"(%1 = OpVariable %2 Function %5
 )");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+    EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
               R"(%7 = OpLoad %3 %1
 %6 = OpFNegate %3 %7
 )");
diff --git a/src/tint/writer/spirv/function.cc b/src/tint/writer/spirv/function.cc
index 871ef3f..8f2499d 100644
--- a/src/tint/writer/spirv/function.cc
+++ b/src/tint/writer/spirv/function.cc
@@ -25,6 +25,8 @@
 
 Function::Function(const Function& other) = default;
 
+Function& Function::operator=(const Function& other) = default;
+
 Function::~Function() = default;
 
 void Function::iterate(std::function<void(const Instruction&)> cb) const {
diff --git a/src/tint/writer/spirv/function.h b/src/tint/writer/spirv/function.h
index 05012f2..ef611c6 100644
--- a/src/tint/writer/spirv/function.h
+++ b/src/tint/writer/spirv/function.h
@@ -38,6 +38,11 @@
     /// Copy constructor
     /// @param other the function to copy
     Function(const Function& other);
+    /// Copy assignment operator
+    /// @param other the function to copy
+    /// @returns the new Function
+    Function& operator=(const Function& other);
+    /// Destructor
     ~Function();
 
     /// Iterates over the function call the cb on each instruction
@@ -84,6 +89,9 @@
         return size;
     }
 
+    /// @returns true if the function has a valid declaration
+    explicit operator bool() const { return declaration_.opcode() == spv::Op::OpFunction; }
+
   private:
     Instruction declaration_;
     Operand label_op_;
diff --git a/src/tint/writer/spirv/generator_impl.cc b/src/tint/writer/spirv/generator_impl.cc
index 0a3f99f..6b4a59b 100644
--- a/src/tint/writer/spirv/generator_impl.cc
+++ b/src/tint/writer/spirv/generator_impl.cc
@@ -175,8 +175,9 @@
 
 bool GeneratorImpl::Generate() {
     if (builder_.Build()) {
-        writer_.WriteHeader(builder_.id_bound());
-        writer_.WriteBuilder(&builder_);
+        auto& module = builder_.Module();
+        writer_.WriteHeader(module.IdBound());
+        writer_.WriteModule(&module);
         return true;
     }
     return false;
diff --git a/src/tint/writer/spirv/instruction.cc b/src/tint/writer/spirv/instruction.cc
index 8b883c1..e2caac6 100644
--- a/src/tint/writer/spirv/instruction.cc
+++ b/src/tint/writer/spirv/instruction.cc
@@ -23,6 +23,8 @@
 
 Instruction::Instruction(const Instruction&) = default;
 
+Instruction& Instruction::operator=(const Instruction&) = default;
+
 Instruction::~Instruction() = default;
 
 uint32_t Instruction::word_length() const {
diff --git a/src/tint/writer/spirv/instruction.h b/src/tint/writer/spirv/instruction.h
index 2beae59..3664335 100644
--- a/src/tint/writer/spirv/instruction.h
+++ b/src/tint/writer/spirv/instruction.h
@@ -31,6 +31,11 @@
     Instruction(spv::Op op, OperandList operands);
     /// Copy Constructor
     Instruction(const Instruction&);
+    /// Copy assignment operator
+    /// @param other the instruction to copy
+    /// @returns the new Instruction
+    Instruction& operator=(const Instruction& other);
+    /// Destructor
     ~Instruction();
 
     /// @returns the instructions op
diff --git a/src/tint/writer/spirv/module.cc b/src/tint/writer/spirv/module.cc
new file mode 100644
index 0000000..3084c79
--- /dev/null
+++ b/src/tint/writer/spirv/module.cc
@@ -0,0 +1,101 @@
+// Copyright 2023 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "src/tint/writer/spirv/module.h"
+
+namespace tint::writer::spirv {
+namespace {
+
+/// Helper to return the size in words of an instruction list when serialized.
+/// @param instructions the instruction list
+/// @returns the number of words needed to serialize the list
+uint32_t SizeOf(const InstructionList& instructions) {
+    uint32_t size = 0;
+    for (const auto& inst : instructions) {
+        size += inst.word_length();
+    }
+    return size;
+}
+
+}  // namespace
+
+Module::Module() {}
+
+Module::~Module() = default;
+
+uint32_t Module::TotalSize() const {
+    // The 5 covers the magic, version, generator, id bound and reserved.
+    uint32_t size = 5;
+
+    size += SizeOf(capabilities_);
+    size += SizeOf(extensions_);
+    size += SizeOf(ext_imports_);
+    size += SizeOf(memory_model_);
+    size += SizeOf(entry_points_);
+    size += SizeOf(execution_modes_);
+    size += SizeOf(debug_);
+    size += SizeOf(annotations_);
+    size += SizeOf(types_);
+    for (const auto& func : functions_) {
+        size += func.word_length();
+    }
+
+    return size;
+}
+
+void Module::Iterate(std::function<void(const Instruction&)> cb) const {
+    for (const auto& inst : capabilities_) {
+        cb(inst);
+    }
+    for (const auto& inst : extensions_) {
+        cb(inst);
+    }
+    for (const auto& inst : ext_imports_) {
+        cb(inst);
+    }
+    for (const auto& inst : memory_model_) {
+        cb(inst);
+    }
+    for (const auto& inst : entry_points_) {
+        cb(inst);
+    }
+    for (const auto& inst : execution_modes_) {
+        cb(inst);
+    }
+    for (const auto& inst : debug_) {
+        cb(inst);
+    }
+    for (const auto& inst : annotations_) {
+        cb(inst);
+    }
+    for (const auto& inst : types_) {
+        cb(inst);
+    }
+    for (const auto& func : functions_) {
+        func.iterate(cb);
+    }
+}
+
+void Module::PushCapability(uint32_t cap) {
+    if (capability_set_.count(cap) == 0) {
+        capability_set_.insert(cap);
+        capabilities_.push_back(Instruction{spv::Op::OpCapability, {Operand(cap)}});
+    }
+}
+
+void Module::PushExtension(const char* extension) {
+    extensions_.push_back(Instruction{spv::Op::OpExtension, {Operand(extension)}});
+}
+
+}  // namespace tint::writer::spirv
diff --git a/src/tint/writer/spirv/module.h b/src/tint/writer/spirv/module.h
new file mode 100644
index 0000000..00caad8
--- /dev/null
+++ b/src/tint/writer/spirv/module.h
@@ -0,0 +1,161 @@
+// Copyright 2023 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef SRC_TINT_WRITER_SPIRV_MODULE_H_
+#define SRC_TINT_WRITER_SPIRV_MODULE_H_
+
+#include <cstdint>
+#include <functional>
+#include <unordered_set>
+#include <vector>
+
+#include "src/tint/writer/spirv/function.h"
+#include "src/tint/writer/spirv/instruction.h"
+
+namespace tint::writer::spirv {
+
+/// A SPIR-V module.
+class Module {
+  public:
+    /// Constructor
+    Module();
+
+    /// Destructor
+    ~Module();
+
+    /// @returns the number of uint32_t's needed to make up the results
+    uint32_t TotalSize() const;
+
+    /// @returns the id bound for this program
+    uint32_t IdBound() const { return next_id_; }
+
+    /// @returns the next id to be used
+    uint32_t NextId() {
+        auto id = next_id_;
+        next_id_ += 1;
+        return id;
+    }
+
+    /// Iterates over all the instructions in the correct order and calls the given callback.
+    /// @param cb the callback to execute
+    void Iterate(std::function<void(const Instruction&)> cb) const;
+
+    /// Add an instruction to the list of capabilities, if the capability hasn't already been added.
+    /// @param cap the capability to set
+    void PushCapability(uint32_t cap);
+
+    /// @returns the capabilities
+    const InstructionList& Capabilities() const { return capabilities_; }
+
+    /// Add an instruction to the list of extensions.
+    /// @param extension the name of the extension
+    void PushExtension(const char* extension);
+
+    /// @returns the extensions
+    const InstructionList& Extensions() const { return extensions_; }
+
+    /// Add an instruction to the list of imported extension instructions.
+    /// @param op the op to set
+    /// @param operands the operands for the instruction
+    void PushExtImport(spv::Op op, const OperandList& operands) {
+        ext_imports_.push_back(Instruction{op, operands});
+    }
+
+    /// @returns the ext imports
+    const InstructionList& ExtImports() const { return ext_imports_; }
+
+    /// Add an instruction to the memory model.
+    /// @param op the op to set
+    /// @param operands the operands for the instruction
+    void PushMemoryModel(spv::Op op, const OperandList& operands) {
+        memory_model_.push_back(Instruction{op, operands});
+    }
+
+    /// @returns the memory model
+    const InstructionList& MemoryModel() const { return memory_model_; }
+
+    /// Add an instruction to the list pf entry points.
+    /// @param op the op to set
+    /// @param operands the operands for the instruction
+    void PushEntryPoint(spv::Op op, const OperandList& operands) {
+        entry_points_.push_back(Instruction{op, operands});
+    }
+    /// @returns the entry points
+    const InstructionList& EntryPoints() const { return entry_points_; }
+
+    /// Add an instruction to the execution mode declarations.
+    /// @param op the op to set
+    /// @param operands the operands for the instruction
+    void PushExecutionMode(spv::Op op, const OperandList& operands) {
+        execution_modes_.push_back(Instruction{op, operands});
+    }
+
+    /// @returns the execution modes
+    const InstructionList& ExecutionModes() const { return execution_modes_; }
+
+    /// Add an instruction to the debug declarations.
+    /// @param op the op to set
+    /// @param operands the operands for the instruction
+    void PushDebug(spv::Op op, const OperandList& operands) {
+        debug_.push_back(Instruction{op, operands});
+    }
+
+    /// @returns the debug instructions
+    const InstructionList& Debug() const { return debug_; }
+
+    /// Add an instruction to the type declarations.
+    /// @param op the op to set
+    /// @param operands the operands for the instruction
+    void PushType(spv::Op op, const OperandList& operands) {
+        types_.push_back(Instruction{op, operands});
+    }
+
+    /// @returns the type instructions
+    const InstructionList& Types() const { return types_; }
+
+    /// Add an instruction to the annotations.
+    /// @param op the op to set
+    /// @param operands the operands for the instruction
+    void PushAnnot(spv::Op op, const OperandList& operands) {
+        annotations_.push_back(Instruction{op, operands});
+    }
+
+    /// @returns the annotations
+    const InstructionList& Annots() const { return annotations_; }
+
+    /// Add a function to the module.
+    /// @param func the function to add
+    void PushFunction(const Function& func) { functions_.push_back(func); }
+
+    /// @returns the functions
+    const std::vector<Function>& Functions() const { return functions_; }
+
+  private:
+    uint32_t next_id_ = 1;
+    InstructionList capabilities_;
+    InstructionList extensions_;
+    InstructionList ext_imports_;
+    InstructionList memory_model_;
+    InstructionList entry_points_;
+    InstructionList execution_modes_;
+    InstructionList debug_;
+    InstructionList types_;
+    InstructionList annotations_;
+    std::vector<Function> functions_;
+    std::unordered_set<uint32_t> capability_set_;
+};
+
+}  // namespace tint::writer::spirv
+
+#endif  // SRC_TINT_WRITER_SPIRV_MODULE_H_
diff --git a/src/tint/writer/spirv/module_test.cc b/src/tint/writer/spirv/module_test.cc
new file mode 100644
index 0000000..07fef6d
--- /dev/null
+++ b/src/tint/writer/spirv/module_test.cc
@@ -0,0 +1,52 @@
+// Copyright 2023 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "src/tint/writer/spirv/spv_dump.h"
+#include "src/tint/writer/spirv/test_helper.h"
+
+namespace tint::writer::spirv {
+namespace {
+
+using SpvModuleTest = TestHelper;
+
+TEST_F(SpvModuleTest, TracksIdBounds) {
+    spirv::Module m;
+
+    for (size_t i = 0; i < 5; i++) {
+        EXPECT_EQ(m.NextId(), i + 1);
+    }
+
+    EXPECT_EQ(6u, m.IdBound());
+}
+
+TEST_F(SpvModuleTest, Capabilities_Dedup) {
+    spirv::Module m;
+
+    m.PushCapability(SpvCapabilityShader);
+    m.PushCapability(SpvCapabilityShader);
+    m.PushCapability(SpvCapabilityShader);
+
+    EXPECT_EQ(DumpInstructions(m.Capabilities()), "OpCapability Shader\n");
+}
+
+TEST_F(SpvModuleTest, DeclareExtension) {
+    spirv::Module m;
+
+    m.PushExtension("SPV_KHR_integer_dot_product");
+
+    EXPECT_EQ(DumpInstructions(m.Extensions()), "OpExtension \"SPV_KHR_integer_dot_product\"\n");
+}
+
+}  // namespace
+}  // namespace tint::writer::spirv
diff --git a/src/tint/writer/spirv/spv_dump.cc b/src/tint/writer/spirv/spv_dump.cc
index 0f95efe..57969eb 100644
--- a/src/tint/writer/spirv/spv_dump.cc
+++ b/src/tint/writer/spirv/spv_dump.cc
@@ -60,8 +60,8 @@
 
 std::string DumpBuilder(Builder& builder) {
     BinaryWriter writer;
-    writer.WriteHeader(builder.id_bound());
-    writer.WriteBuilder(&builder);
+    writer.WriteHeader(builder.Module().IdBound());
+    writer.WriteModule(&builder.Module());
     return Disassemble(writer.result());
 }
 
diff --git a/src/tint/writer/spirv/test_helper.h b/src/tint/writer/spirv/test_helper.h
index 028d363..b9a90be 100644
--- a/src/tint/writer/spirv/test_helper.h
+++ b/src/tint/writer/spirv/test_helper.h
@@ -94,8 +94,8 @@
     /// @param b the spirv::Builder containing the built SPIR-V module
     void Validate(spirv::Builder& b) {
         BinaryWriter writer;
-        writer.WriteHeader(b.id_bound());
-        writer.WriteBuilder(&b);
+        writer.WriteHeader(b.Module().IdBound());
+        writer.WriteModule(&b.Module());
         auto binary = writer.result();
 
         std::string spv_errors;