spirv-reader: update tests to wrap parser impl

This is a step to being able to dump the SPIR-V for
successfully converted modules.

Bug: tint:756
Change-Id: Ifa48c88835ff10824c542a4e13d8a2d3a7f7f484
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/49604
Commit-Queue: David Neto <dneto@google.com>
Auto-Submit: David Neto <dneto@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
diff --git a/src/reader/spirv/function.cc b/src/reader/spirv/function.cc
index 0027042..be82b9a 100644
--- a/src/reader/spirv/function.cc
+++ b/src/reader/spirv/function.cc
@@ -743,6 +743,23 @@
                                  const spvtools::opt::Function& function)
     : FunctionEmitter(pi, function, nullptr) {}
 
+FunctionEmitter::FunctionEmitter(FunctionEmitter&& other)
+    : parser_impl_(other.parser_impl_),
+      builder_(other.builder_),
+      ir_context_(other.ir_context_),
+      def_use_mgr_(ir_context_.get_def_use_mgr()),
+      constant_mgr_(ir_context_.get_constant_mgr()),
+      type_mgr_(ir_context_.get_type_mgr()),
+      fail_stream_(other.fail_stream_),
+      namer_(other.namer_),
+      function_(other.function_),
+      sample_mask_in_id(other.sample_mask_out_id),
+      sample_mask_out_id(other.sample_mask_in_id),
+      ep_info_(other.ep_info_) {
+  other.statements_stack_.clear();
+  PushNewStatementBlock(nullptr, 0, nullptr);
+}
+
 FunctionEmitter::~FunctionEmitter() = default;
 
 FunctionEmitter::StatementBlock::StatementBlock(
diff --git a/src/reader/spirv/function.h b/src/reader/spirv/function.h
index 24393dd..bb3a138 100644
--- a/src/reader/spirv/function.h
+++ b/src/reader/spirv/function.h
@@ -397,6 +397,9 @@
   FunctionEmitter(ParserImpl* pi,
                   const spvtools::opt::Function& function,
                   const EntryPointInfo* ep_info);
+  /// Move constructor. Only valid when the other object was newly created.
+  /// @param other the emitter to clone
+  FunctionEmitter(FunctionEmitter&& other);
   /// Destructor
   ~FunctionEmitter();
 
diff --git a/src/reader/spirv/function_arithmetic_test.cc b/src/reader/spirv/function_arithmetic_test.cc
index 869729a..4e8ee20 100644
--- a/src/reader/spirv/function_arithmetic_test.cc
+++ b/src/reader/spirv/function_arithmetic_test.cc
@@ -146,7 +146,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(
   VariableConst{
@@ -172,7 +172,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(
   VariableConst{
@@ -200,7 +200,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(
   VariableConst{
@@ -228,7 +228,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(
   VariableConst{
@@ -258,7 +258,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(
   VariableConst{
@@ -288,7 +288,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(
   VariableConst{
@@ -320,7 +320,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(
   VariableConst{
@@ -352,7 +352,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(
   VariableConst{
@@ -386,7 +386,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(
   VariableConst{
@@ -412,7 +412,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(
   VariableConst{
@@ -467,7 +467,7 @@
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions())
       << p->error() << "\n"
       << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   std::ostringstream ss;
   ss << R"(VariableConst{
@@ -512,7 +512,7 @@
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions())
       << p->error() << "\n"
       << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   std::ostringstream ss;
   ss << R"(VariableConst{
@@ -990,7 +990,7 @@
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions())
       << p->error() << "\n"
       << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(
   VariableConst{
@@ -1025,7 +1025,7 @@
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions())
       << p->error() << "\n"
       << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(
   VariableConst{
@@ -1135,7 +1135,7 @@
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions())
       << p->error() << "\n"
       << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(
   VariableConst{
@@ -1170,7 +1170,7 @@
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions())
       << p->error() << "\n"
       << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(
   VariableConst{
@@ -1222,7 +1222,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{
     x_10
@@ -1250,7 +1250,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{
     x_10
@@ -1278,7 +1278,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{
     x_10
@@ -1306,7 +1306,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{
     x_10
@@ -1334,7 +1334,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{
     x_10
@@ -1362,7 +1362,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{
     x_3
@@ -1394,7 +1394,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto got = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(got, HasSubstr(R"(VariableConst{
@@ -1520,7 +1520,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{
     x_2
@@ -1566,7 +1566,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   const auto* expected = R"(
 VariableDeclStatement{
@@ -1599,7 +1599,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   // Note, in the AST dump mat_2_3 means 2 rows and 3 columns.
   // So the column vectors have 2 elements.
@@ -1635,7 +1635,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   const auto* expected = R"(
 VariableDeclStatement{
diff --git a/src/reader/spirv/function_bit_test.cc b/src/reader/spirv/function_bit_test.cc
index 3873ec0..9360545 100644
--- a/src/reader/spirv/function_bit_test.cc
+++ b/src/reader/spirv/function_bit_test.cc
@@ -149,7 +149,7 @@
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions())
       << p->error() << "\n"
       << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   std::ostringstream ss;
   ss << R"(VariableConst{
@@ -194,7 +194,7 @@
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions())
       << p->error() << "\n"
       << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   std::ostringstream ss;
   ss << R"(VariableConst{
@@ -692,7 +692,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(
   VariableConst{
@@ -718,7 +718,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(
   VariableConst{
@@ -746,7 +746,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(
   VariableConst{
@@ -774,7 +774,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(
   VariableConst{
@@ -800,7 +800,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(
   VariableConst{
@@ -830,7 +830,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(
   VariableConst{
@@ -862,7 +862,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(
   VariableConst{
@@ -893,7 +893,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(
   VariableConst{
@@ -947,7 +947,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   const auto body = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(body, HasSubstr(R"(
@@ -975,7 +975,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   const auto body = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(body, HasSubstr(R"(
@@ -1005,7 +1005,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   const auto body = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(body, HasSubstr(R"(
@@ -1035,7 +1035,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   const auto body = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(body, HasSubstr(R"(
@@ -1063,7 +1063,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   const auto body = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(body, HasSubstr(R"(
@@ -1091,7 +1091,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   const auto body = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(body, HasSubstr(R"(
@@ -1121,7 +1121,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   const auto body = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(body, HasSubstr(R"(
@@ -1151,7 +1151,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   const auto body = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(body, HasSubstr(R"(
@@ -1179,7 +1179,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   const auto body = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(body, HasSubstr(R"(
@@ -1207,7 +1207,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   const auto body = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(body, HasSubstr(R"(
@@ -1237,7 +1237,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   const auto body = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(body, HasSubstr(R"(
@@ -1267,7 +1267,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   const auto body = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(body, HasSubstr(R"(
@@ -1295,7 +1295,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   const auto body = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(body, HasSubstr(R"(
@@ -1323,7 +1323,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   const auto body = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(body, HasSubstr(R"(
@@ -1353,7 +1353,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   const auto body = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(body, HasSubstr(R"(
@@ -1383,7 +1383,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   const auto body = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(body, HasSubstr(R"(
diff --git a/src/reader/spirv/function_call_test.cc b/src/reader/spirv/function_call_test.cc
index e7aa477..0206f1d 100644
--- a/src/reader/spirv/function_call_test.cc
+++ b/src/reader/spirv/function_call_test.cc
@@ -85,7 +85,7 @@
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
   {
-    FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+    auto fe = p->function_emitter(100);
     EXPECT_TRUE(fe.EmitBody());
     EXPECT_THAT(ToString(p->builder(), fe.ast_body()),
                 HasSubstr(R"(VariableDeclStatement{
@@ -106,7 +106,7 @@
   }
 
   {
-    FunctionEmitter fe(p.get(), *spirv_function(p.get(), 50));
+    auto fe = p->function_emitter(50);
     EXPECT_TRUE(fe.EmitBody());
     EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(Return{
   {
@@ -141,7 +141,7 @@
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
   {
-    FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+    auto fe = p->function_emitter(100);
     EXPECT_TRUE(fe.EmitBody()) << p->error();
     EXPECT_THAT(ToString(p->builder(), fe.ast_body()),
                 HasSubstr(R"(VariableDeclStatement{
@@ -176,7 +176,7 @@
 Return{})"));
   }
   {
-    FunctionEmitter fe(p.get(), *spirv_function(p.get(), 50));
+    auto fe = p->function_emitter(50);
     EXPECT_TRUE(fe.EmitBody()) << p->error();
     EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(Return{
   {
diff --git a/src/reader/spirv/function_cfg_test.cc b/src/reader/spirv/function_cfg_test.cc
index af99038..d5f1869 100644
--- a/src/reader/spirv/function_cfg_test.cc
+++ b/src/reader/spirv/function_cfg_test.cc
@@ -129,7 +129,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   EXPECT_TRUE(fe.TerminatorsAreValid());
 }
@@ -147,7 +147,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   EXPECT_TRUE(fe.TerminatorsAreValid()) << p->error();
 }
@@ -172,7 +172,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   EXPECT_TRUE(fe.TerminatorsAreValid()) << p->error();
 }
@@ -200,7 +200,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   EXPECT_TRUE(fe.TerminatorsAreValid());
 }
@@ -222,7 +222,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   EXPECT_TRUE(fe.TerminatorsAreValid());
 }
@@ -250,7 +250,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   EXPECT_TRUE(fe.TerminatorsAreValid());
 }
@@ -265,7 +265,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   EXPECT_TRUE(fe.TerminatorsAreValid());
 }
@@ -280,7 +280,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   EXPECT_TRUE(fe.TerminatorsAreValid());
 }
@@ -310,7 +310,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   EXPECT_FALSE(fe.TerminatorsAreValid());
   EXPECT_THAT(p->error(), Eq("Block 20 branches to function entry block 10"));
@@ -326,7 +326,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   EXPECT_FALSE(fe.TerminatorsAreValid());
   EXPECT_THAT(p->error(),
@@ -352,7 +352,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   EXPECT_FALSE(fe.TerminatorsAreValid());
   EXPECT_THAT(p->error(), Eq("Block 10 in function 100 branches to 210 which "
@@ -369,7 +369,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   EXPECT_TRUE(fe.RegisterMerges());
 
@@ -399,7 +399,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   EXPECT_TRUE(fe.RegisterMerges());
 
@@ -448,7 +448,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   EXPECT_TRUE(fe.RegisterMerges());
 
@@ -497,7 +497,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   EXPECT_TRUE(fe.RegisterMerges());
 
@@ -550,7 +550,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   EXPECT_TRUE(fe.RegisterMerges());
 
@@ -606,7 +606,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   EXPECT_TRUE(fe.RegisterMerges());
 
@@ -663,7 +663,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   EXPECT_TRUE(fe.RegisterMerges());
 
@@ -712,7 +712,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   EXPECT_FALSE(fe.RegisterMerges());
   EXPECT_THAT(p->error(), Eq("Selection header 10 does not end in an "
@@ -742,7 +742,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   EXPECT_FALSE(fe.RegisterMerges());
   EXPECT_THAT(p->error(), Eq("Loop header 20 does not end in an OpBranch or "
@@ -766,7 +766,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   EXPECT_FALSE(fe.RegisterMerges());
   EXPECT_THAT(p->error(),
@@ -790,7 +790,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   EXPECT_FALSE(fe.RegisterMerges());
   EXPECT_THAT(p->error(),
@@ -824,7 +824,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   EXPECT_FALSE(fe.RegisterMerges());
   EXPECT_THAT(
@@ -849,7 +849,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   EXPECT_FALSE(fe.RegisterMerges());
   EXPECT_THAT(p->error(),
@@ -873,7 +873,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   EXPECT_FALSE(fe.RegisterMerges());
   EXPECT_THAT(p->error(),
@@ -901,7 +901,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   EXPECT_FALSE(fe.RegisterMerges());
   EXPECT_THAT(p->error(),
@@ -945,7 +945,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   EXPECT_FALSE(fe.RegisterMerges());
   EXPECT_THAT(p->error(), Eq("Block 40 declared as continue target for more "
@@ -972,7 +972,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   EXPECT_FALSE(fe.RegisterMerges());
   EXPECT_THAT(
@@ -990,7 +990,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
 
@@ -1017,7 +1017,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
 
@@ -1040,7 +1040,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
 
@@ -1063,7 +1063,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
 
@@ -1086,7 +1086,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
 
@@ -1120,7 +1120,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
 
@@ -1147,7 +1147,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
 
@@ -1171,7 +1171,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
 
@@ -1195,7 +1195,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
 
@@ -1222,7 +1222,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
 
@@ -1253,7 +1253,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
 
@@ -1283,7 +1283,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
 
@@ -1317,7 +1317,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
 
@@ -1353,7 +1353,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
 
@@ -1386,7 +1386,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
 
@@ -1423,7 +1423,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
 
@@ -1465,7 +1465,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
 
@@ -1514,7 +1514,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
 
@@ -1564,7 +1564,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
 
@@ -1614,7 +1614,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
 
@@ -1658,7 +1658,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
 
@@ -1683,7 +1683,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
 
@@ -1707,7 +1707,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
 
@@ -1731,7 +1731,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
 
@@ -1760,7 +1760,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
 
@@ -1789,7 +1789,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
 
@@ -1818,7 +1818,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
 
@@ -1850,7 +1850,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
 
@@ -1883,7 +1883,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
 
@@ -1923,7 +1923,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
 
@@ -1960,7 +1960,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
 
@@ -1993,7 +1993,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
 
@@ -2026,7 +2026,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
 
@@ -2063,7 +2063,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
 
@@ -2103,7 +2103,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
 
@@ -2145,7 +2145,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
 
@@ -2185,7 +2185,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
 
@@ -2218,7 +2218,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
 
@@ -2250,7 +2250,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
 
@@ -2289,7 +2289,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
 
@@ -2318,7 +2318,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
 
@@ -2347,7 +2347,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
 
@@ -2376,7 +2376,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
 
@@ -2418,7 +2418,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
 
@@ -2461,7 +2461,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
 
@@ -2504,7 +2504,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
 
@@ -2547,7 +2547,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
 
@@ -2590,7 +2590,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
 
@@ -2638,7 +2638,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
 
@@ -2667,7 +2667,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
   fe.RegisterMerges();
@@ -2692,7 +2692,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
   fe.RegisterMerges();
@@ -2720,7 +2720,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
   fe.RegisterMerges();
@@ -2752,7 +2752,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
   fe.RegisterMerges();
@@ -2790,7 +2790,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
   fe.RegisterMerges();
@@ -2827,7 +2827,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
   fe.RegisterMerges();
@@ -2850,7 +2850,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
   fe.RegisterMerges();
@@ -2877,7 +2877,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
   fe.RegisterMerges();
@@ -2912,7 +2912,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
   fe.RegisterMerges();
@@ -2959,7 +2959,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
   fe.RegisterMerges();
@@ -3003,7 +3003,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
   fe.RegisterMerges();
@@ -3040,7 +3040,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
   fe.RegisterMerges();
@@ -3088,7 +3088,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
   fe.RegisterMerges();
@@ -3137,7 +3137,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
   fe.RegisterMerges();
@@ -3181,7 +3181,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
   fe.RegisterMerges();
@@ -3230,7 +3230,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
   fe.RegisterMerges();
@@ -3289,7 +3289,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
   fe.RegisterMerges();
@@ -3349,7 +3349,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
   fe.RegisterMerges();
@@ -3399,7 +3399,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
   fe.RegisterMerges();
@@ -3453,7 +3453,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
   fe.RegisterMerges();
@@ -3508,7 +3508,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
   fe.RegisterMerges();
@@ -3559,7 +3559,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
   fe.RegisterMerges();
@@ -3603,7 +3603,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
   fe.RegisterMerges();
@@ -3652,7 +3652,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
   fe.RegisterMerges();
@@ -3705,7 +3705,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   ASSERT_TRUE(FlowLabelControlFlowConstructs(&fe)) << p->error();
   const auto& constructs = fe.constructs();
   EXPECT_EQ(constructs.size(), 4u);
@@ -3745,7 +3745,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
   EXPECT_TRUE(fe.VerifyHeaderContinueMergeOrder());
@@ -3777,7 +3777,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
   EXPECT_TRUE(fe.VerifyHeaderContinueMergeOrder());
@@ -3812,7 +3812,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
   EXPECT_TRUE(fe.VerifyHeaderContinueMergeOrder());
@@ -3851,7 +3851,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
   EXPECT_TRUE(fe.VerifyHeaderContinueMergeOrder());
@@ -3895,7 +3895,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
   EXPECT_TRUE(fe.VerifyHeaderContinueMergeOrder());
@@ -3924,7 +3924,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
   EXPECT_TRUE(fe.VerifyHeaderContinueMergeOrder());
@@ -3953,7 +3953,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
   EXPECT_TRUE(fe.VerifyHeaderContinueMergeOrder());
@@ -3984,7 +3984,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
   EXPECT_TRUE(fe.VerifyHeaderContinueMergeOrder());
@@ -4015,7 +4015,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
   EXPECT_TRUE(fe.VerifyHeaderContinueMergeOrder());
@@ -4051,7 +4051,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
   EXPECT_TRUE(fe.VerifyHeaderContinueMergeOrder());
@@ -4091,7 +4091,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
   EXPECT_TRUE(fe.VerifyHeaderContinueMergeOrder());
@@ -4113,7 +4113,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
   EXPECT_TRUE(fe.VerifyHeaderContinueMergeOrder());
@@ -4147,7 +4147,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
   EXPECT_TRUE(fe.VerifyHeaderContinueMergeOrder());
@@ -4185,7 +4185,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
   EXPECT_TRUE(fe.VerifyHeaderContinueMergeOrder());
@@ -4223,7 +4223,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
   EXPECT_TRUE(fe.VerifyHeaderContinueMergeOrder());
@@ -4258,7 +4258,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
   EXPECT_TRUE(fe.VerifyHeaderContinueMergeOrder());
@@ -4296,7 +4296,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
   EXPECT_TRUE(fe.VerifyHeaderContinueMergeOrder());
@@ -4326,7 +4326,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
   EXPECT_TRUE(fe.VerifyHeaderContinueMergeOrder());
@@ -4369,7 +4369,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(FlowClassifyCFGEdges(&fe)) << p->error();
   // Some further processing
   EXPECT_THAT(
@@ -4400,7 +4400,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(FlowClassifyCFGEdges(&fe)) << p->error();
   EXPECT_THAT(p->error(), Eq("Invalid function exit at block 50 from continue "
                              "construct starting at 50"));
@@ -4428,7 +4428,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(FlowClassifyCFGEdges(&fe));
   EXPECT_THAT(p->error(), Eq("Invalid function exit at block 50 from continue "
                              "construct starting at 50"));
@@ -4456,7 +4456,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(FlowClassifyCFGEdges(&fe));
   EXPECT_THAT(p->error(), Eq("Invalid function exit at block 50 from continue "
                              "construct starting at 50"));
@@ -4484,7 +4484,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(FlowClassifyCFGEdges(&fe));
   EXPECT_THAT(
       p->error(),
@@ -4517,7 +4517,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(FlowClassifyCFGEdges(&fe));
   EXPECT_THAT(p->error(),
               Eq("Invalid exit (50->20) from continue construct: 50 is not the "
@@ -4551,7 +4551,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(FlowClassifyCFGEdges(&fe));
   EXPECT_THAT(p->error(), Eq("Invalid backedge (50->10): does not branch to "
                              "the corresponding loop header, expected 20"));
@@ -4573,7 +4573,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(FlowClassifyCFGEdges(&fe));
 
   auto* bi20 = fe.GetBlockInfo(20);
@@ -4605,7 +4605,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(FlowClassifyCFGEdges(&fe));
 
   auto* bi40 = fe.GetBlockInfo(40);
@@ -4641,7 +4641,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(FlowClassifyCFGEdges(&fe));
 
   auto* bi50 = fe.GetBlockInfo(50);
@@ -4677,7 +4677,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(FlowClassifyCFGEdges(&fe)) << p->error();
 
   auto* bi50 = fe.GetBlockInfo(50);
@@ -4711,7 +4711,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(FlowClassifyCFGEdges(&fe));
   EXPECT_THAT(p->error(),
               Eq("Invalid exit (40->99) from continue construct: 40 is not the "
@@ -4736,7 +4736,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(FlowClassifyCFGEdges(&fe));
 
   auto* bi = fe.GetBlockInfo(20);
@@ -4764,7 +4764,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(FlowClassifyCFGEdges(&fe));
 
   auto* bi = fe.GetBlockInfo(20);
@@ -4795,7 +4795,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(FlowClassifyCFGEdges(&fe));
 
   auto* bi = fe.GetBlockInfo(20);
@@ -4823,7 +4823,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(FlowClassifyCFGEdges(&fe));
 
   auto* bi = fe.GetBlockInfo(30);
@@ -4848,7 +4848,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(FlowClassifyCFGEdges(&fe));
 
   auto* bi = fe.GetBlockInfo(20);
@@ -4876,7 +4876,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(FlowClassifyCFGEdges(&fe));
 
   // Then clause
@@ -4911,7 +4911,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(FlowClassifyCFGEdges(&fe));
   EXPECT_THAT(
       p->error(),
@@ -4951,7 +4951,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(FlowClassifyCFGEdges(&fe));
   EXPECT_THAT(
       p->error(),
@@ -4975,7 +4975,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(FlowClassifyCFGEdges(&fe));
 
   auto* bi = fe.GetBlockInfo(10);
@@ -5000,7 +5000,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(FlowClassifyCFGEdges(&fe));
 
   auto* bi = fe.GetBlockInfo(20);
@@ -5028,7 +5028,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(FlowClassifyCFGEdges(&fe));
 
   auto* bi = fe.GetBlockInfo(30);
@@ -5053,7 +5053,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(FlowClassifyCFGEdges(&fe));
 
   auto* bi = fe.GetBlockInfo(10);
@@ -5085,7 +5085,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(FlowClassifyCFGEdges(&fe));
 
   auto* bi = fe.GetBlockInfo(30);
@@ -5117,7 +5117,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(FlowClassifyCFGEdges(&fe));
 
   auto* bi = fe.GetBlockInfo(30);
@@ -5145,7 +5145,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(FlowClassifyCFGEdges(&fe));
   EXPECT_THAT(
       p->error(),
@@ -5180,7 +5180,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(FlowClassifyCFGEdges(&fe));
   EXPECT_THAT(
       p->error(),
@@ -5212,7 +5212,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(FlowClassifyCFGEdges(&fe));
   EXPECT_THAT(
       p->error(),
@@ -5242,7 +5242,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(FlowClassifyCFGEdges(&fe));
 
   auto* bi = fe.GetBlockInfo(30);
@@ -5276,7 +5276,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(FlowClassifyCFGEdges(&fe));
 
   auto* bi = fe.GetBlockInfo(60);
@@ -5307,7 +5307,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(FlowClassifyCFGEdges(&fe));
 
   auto* bi = fe.GetBlockInfo(30);
@@ -5346,7 +5346,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(FlowClassifyCFGEdges(&fe));
 
   auto* bi = fe.GetBlockInfo(40);
@@ -5385,7 +5385,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(FlowClassifyCFGEdges(&fe));
 
   auto* bi = fe.GetBlockInfo(40);
@@ -5427,7 +5427,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(FlowClassifyCFGEdges(&fe));
   EXPECT_THAT(p->error(),
               Eq("Invalid exit (50->99) from continue construct: 50 is not the "
@@ -5461,7 +5461,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(FlowClassifyCFGEdges(&fe));
   EXPECT_THAT(
       p->error(),
@@ -5498,7 +5498,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(FlowClassifyCFGEdges(&fe));
   EXPECT_THAT(
       p->error(),
@@ -5528,7 +5528,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(FlowClassifyCFGEdges(&fe));
 
   auto* bi = fe.GetBlockInfo(30);
@@ -5566,7 +5566,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(FlowClassifyCFGEdges(&fe));
 
   auto* bi = fe.GetBlockInfo(40);
@@ -5604,7 +5604,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(FlowClassifyCFGEdges(&fe));
 
   auto* bi = fe.GetBlockInfo(40);
@@ -5643,7 +5643,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(FlowClassifyCFGEdges(&fe)) << p->error();
 
   auto* bi = fe.GetBlockInfo(40);
@@ -5679,7 +5679,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
   EXPECT_TRUE(fe.VerifyHeaderContinueMergeOrder());
@@ -5717,7 +5717,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
   EXPECT_TRUE(fe.VerifyHeaderContinueMergeOrder());
@@ -5758,7 +5758,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(FlowClassifyCFGEdges(&fe)) << p->error();
 
   auto* bi = fe.GetBlockInfo(40);
@@ -5798,7 +5798,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(FlowClassifyCFGEdges(&fe));
 
   auto* bi = fe.GetBlockInfo(40);
@@ -5849,7 +5849,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(FlowClassifyCFGEdges(&fe));
   EXPECT_THAT(
       p->error(),
@@ -5879,7 +5879,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(FlowClassifyCFGEdges(&fe));
 
   auto* bi = fe.GetBlockInfo(30);
@@ -5910,7 +5910,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(FlowClassifyCFGEdges(&fe));
 
   auto* bi = fe.GetBlockInfo(30);
@@ -5941,7 +5941,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(FlowClassifyCFGEdges(&fe));
 
   auto* bi = fe.GetBlockInfo(30);
@@ -5981,7 +5981,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(FlowClassifyCFGEdges(&fe));
   EXPECT_THAT(
       p->error(),
@@ -6015,7 +6015,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(FlowClassifyCFGEdges(&fe));
   EXPECT_THAT(p->error(),
               Eq("Control flow diverges at block 20 (to 25, 30) but it is not "
@@ -6061,7 +6061,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(FlowClassifyCFGEdges(&fe));
   EXPECT_THAT(p->error(),
               Eq("Invalid exit (40->20) from continue construct: 40 is not the "
@@ -6100,7 +6100,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(FlowFindSwitchCaseHeaders(&fe));
   EXPECT_THAT(fe.block_order(), ElementsAre(10, 20, 40, 50, 99));
   EXPECT_THAT(p->error(),
@@ -6143,7 +6143,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(FlowClassifyCFGEdges(&fe));
   EXPECT_THAT(p->error(), Eq("Branch from 10 to 50 bypasses continue target 40 "
                              "(dominance rule violated)"));
@@ -6184,7 +6184,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(FlowClassifyCFGEdges(&fe));
   EXPECT_THAT(fe.block_order(), ElementsAre(10, 20, 40, 50, 49, 99));
   EXPECT_THAT(p->error(), Eq("Branch from 10 to 50 bypasses continue target 40 "
@@ -6228,7 +6228,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(FlowClassifyCFGEdges(&fe));
   EXPECT_THAT(
       p->error(),
@@ -6274,7 +6274,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(FlowClassifyCFGEdges(&fe));
   EXPECT_THAT(
       p->error(),
@@ -6297,7 +6297,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(FlowClassifyCFGEdges(&fe));
 
   auto* bi = fe.GetBlockInfo(10);
@@ -6322,7 +6322,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(FlowClassifyCFGEdges(&fe));
 
   auto* bi = fe.GetBlockInfo(10);
@@ -6347,7 +6347,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(FlowClassifyCFGEdges(&fe));
 
   auto* bi = fe.GetBlockInfo(10);
@@ -6375,7 +6375,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(FlowClassifyCFGEdges(&fe));
 
   auto* bi = fe.GetBlockInfo(10);
@@ -6406,7 +6406,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(FlowClassifyCFGEdges(&fe));
 
   auto* bi = fe.GetBlockInfo(20);
@@ -6439,7 +6439,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(FlowClassifyCFGEdges(&fe));
   EXPECT_THAT(
       p->error(),
@@ -6470,7 +6470,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(FlowClassifyCFGEdges(&fe));
   EXPECT_THAT(
       p->error(),
@@ -6504,7 +6504,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(FlowClassifyCFGEdges(&fe));
   EXPECT_THAT(p->error(),
               // Weird error, but still we caught it.
@@ -6544,7 +6544,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(FlowClassifyCFGEdges(&fe));
   EXPECT_THAT(
       p->error(),
@@ -6578,7 +6578,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(FlowClassifyCFGEdges(&fe));
   EXPECT_THAT(
       p->error(),
@@ -6611,7 +6611,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(FlowFindSwitchCaseHeaders(&fe));
   EXPECT_THAT(p->error(),
               Eq("Block 50 is a case block for switch-selection header 10 and "
@@ -6643,7 +6643,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(FlowFindSwitchCaseHeaders(&fe));
   EXPECT_THAT(p->error(),
               Eq("Block 50 is the default block for switch-selection header 10 "
@@ -6672,7 +6672,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(FlowClassifyCFGEdges(&fe));
   EXPECT_THAT(
       p->error(),
@@ -6697,7 +6697,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(FlowClassifyCFGEdges(&fe));
   EXPECT_THAT(p->error(),
               Eq("Control flow diverges at block 20 (to 30, 40) but it is not "
@@ -6722,7 +6722,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(FlowClassifyCFGEdges(&fe));
   EXPECT_THAT(p->error(),
               Eq("Control flow diverges at block 10 (to 99, 20) but it is not "
@@ -6756,7 +6756,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(FlowClassifyCFGEdges(&fe));
 
   auto* bi = fe.GetBlockInfo(20);
@@ -6793,7 +6793,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(FlowClassifyCFGEdges(&fe));
 
   auto* bi20 = fe.GetBlockInfo(20);
@@ -6834,7 +6834,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(FlowClassifyCFGEdges(&fe));
 
   auto* bi10 = fe.GetBlockInfo(10);
@@ -6857,7 +6857,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(FlowClassifyCFGEdges(&fe));
 
   auto* bi = fe.GetBlockInfo(10);
@@ -6886,7 +6886,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(FlowFindIfSelectionInternalHeaders(&fe));
 
   auto* bi10 = fe.GetBlockInfo(10);
@@ -6930,7 +6930,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(FlowFindIfSelectionInternalHeaders(&fe));
 
   auto* bi10 = fe.GetBlockInfo(10);
@@ -6968,7 +6968,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(FlowFindIfSelectionInternalHeaders(&fe));
 
   auto* bi10 = fe.GetBlockInfo(10);
@@ -7009,7 +7009,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(FlowFindIfSelectionInternalHeaders(&fe));
 
   EXPECT_THAT(fe.block_order(), ElementsAre(10, 20, 80, 99));
@@ -7043,7 +7043,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(FlowFindIfSelectionInternalHeaders(&fe));
 
   EXPECT_THAT(fe.block_order(), ElementsAre(10, 20, 30, 80, 99));
@@ -7078,7 +7078,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(FlowFindIfSelectionInternalHeaders(&fe));
 
   EXPECT_THAT(fe.block_order(), ElementsAre(10, 20, 30, 80, 99));
@@ -7113,7 +7113,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(FlowFindIfSelectionInternalHeaders(&fe));
 
   EXPECT_THAT(fe.block_order(), ElementsAre(10, 30, 20, 80, 99));
@@ -7154,7 +7154,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   // Error out sooner in the flow
   EXPECT_FALSE(FlowClassifyCFGEdges(&fe));
   EXPECT_THAT(p->error(),
@@ -7183,7 +7183,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(FlowClassifyCFGEdges(&fe));
   EXPECT_THAT(fe.block_order(), ElementsAre(10, 20, 80, 99));
 
@@ -7221,7 +7221,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(FlowClassifyCFGEdges(&fe));
   EXPECT_THAT(fe.block_order(), ElementsAre(10, 20, 30, 80, 99));
 
@@ -7258,7 +7258,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(FlowClassifyCFGEdges(&fe));
   EXPECT_THAT(fe.block_order(), ElementsAre(10, 20, 30, 80, 99));
 
@@ -7297,7 +7297,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(FlowFindIfSelectionInternalHeaders(&fe));
   EXPECT_THAT(
       p->error(),
@@ -7330,7 +7330,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(FlowFindIfSelectionInternalHeaders(&fe));
   EXPECT_THAT(
       p->error(),
@@ -7369,7 +7369,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(FlowFindIfSelectionInternalHeaders(&fe));
   EXPECT_THAT(p->error(),
               Eq("Block 70 is the merge block for 50 but has alternate paths "
@@ -7408,7 +7408,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(FlowFindIfSelectionInternalHeaders(&fe));
   EXPECT_THAT(p->error(), Eq(""));
 }
@@ -7444,7 +7444,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(FlowFindIfSelectionInternalHeaders(&fe));
   EXPECT_THAT(p->error(), Eq(""));
 }
@@ -7474,7 +7474,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(FlowFindIfSelectionInternalHeaders(&fe));
   EXPECT_THAT(p->error(), Eq(""));
 }
@@ -7509,7 +7509,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(FlowFindIfSelectionInternalHeaders(&fe));
   EXPECT_THAT(p->error(), Eq(""));
 }
@@ -7545,7 +7545,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(FlowFindIfSelectionInternalHeaders(&fe));
   EXPECT_THAT(p->error(), Eq(""));
 }
@@ -7575,7 +7575,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(FlowFindIfSelectionInternalHeaders(&fe));
   EXPECT_THAT(p->error(), Eq(""));
 }
@@ -7610,7 +7610,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto got = ToString(p->builder(), fe.ast_body());
   auto* expect = R"(Assignment{
@@ -7722,7 +7722,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto got = ToString(p->builder(), fe.ast_body());
   auto* expect = R"(Assignment{
@@ -7849,7 +7849,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error() << assembly;
   auto got = ToString(p->builder(), fe.ast_body());
   auto* expect = R"(Assignment{
@@ -8017,7 +8017,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   fe.RegisterBasicBlocks();
   fe.ComputeBlockOrderAndPositions();
   EXPECT_TRUE(fe.VerifyHeaderContinueMergeOrder());
@@ -8039,7 +8039,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -8075,7 +8075,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -8123,7 +8123,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -8179,7 +8179,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -8246,7 +8246,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -8318,7 +8318,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -8382,7 +8382,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -8467,7 +8467,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -8557,7 +8557,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -8612,7 +8612,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -8663,7 +8663,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -8706,7 +8706,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -8757,7 +8757,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -8822,7 +8822,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -8896,7 +8896,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -8969,7 +8969,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto got = ToString(p->builder(), fe.ast_body());
   auto* expect = R"(Assignment{
@@ -9027,7 +9027,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto got = ToString(p->builder(), fe.ast_body());
   auto* expect = R"(Loop{
@@ -9087,7 +9087,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto got = ToString(p->builder(), fe.ast_body());
   auto* expect = R"(Loop{
@@ -9154,7 +9154,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto got = ToString(p->builder(), fe.ast_body());
   auto* expect = R"(Loop{
@@ -9228,7 +9228,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto got = ToString(p->builder(), fe.ast_body());
   auto* expect = R"(Loop{
@@ -9285,7 +9285,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -9334,7 +9334,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -9390,7 +9390,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -9452,7 +9452,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -9514,7 +9514,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -9567,7 +9567,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -9612,7 +9612,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -9666,7 +9666,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -9726,7 +9726,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -9792,7 +9792,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -9863,7 +9863,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -9935,7 +9935,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -10005,7 +10005,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -10057,7 +10057,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -10083,7 +10083,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -10123,7 +10123,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -10153,7 +10153,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 200));
+  auto fe = p->function_emitter(200);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -10192,7 +10192,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 200));
+  auto fe = p->function_emitter(200);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -10249,7 +10249,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 200));
+  auto fe = p->function_emitter(200);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -10279,7 +10279,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -10305,7 +10305,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -10345,7 +10345,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -10367,7 +10367,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -10393,7 +10393,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -10433,7 +10433,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -10463,7 +10463,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 200));
+  auto fe = p->function_emitter(200);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -10497,7 +10497,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -10532,7 +10532,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -10569,7 +10569,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -10629,7 +10629,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -10700,7 +10700,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -10753,7 +10753,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(fe.EmitBody()) << p->error();
   EXPECT_THAT(p->error(),
               Eq("Invalid exit (40->99) from continue construct: 40 is not the "
@@ -10783,7 +10783,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto got = ToString(p->builder(), fe.ast_body());
   auto* expect = R"(Loop{
@@ -10825,7 +10825,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto got = ToString(p->builder(), fe.ast_body());
   auto* expect = R"(Loop{
@@ -10879,7 +10879,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto got = ToString(p->builder(), fe.ast_body());
   auto* expect = R"(Loop{
@@ -10948,7 +10948,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto got = ToString(p->builder(), fe.ast_body());
   auto* expect = R"(Assignment{
@@ -11018,7 +11018,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto got = ToString(p->builder(), fe.ast_body());
   auto* expect = R"(If{
@@ -11061,7 +11061,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto got = ToString(p->builder(), fe.ast_body());
   auto* expect = R"(If{
@@ -11112,7 +11112,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -11164,7 +11164,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto got = ToString(p->builder(), fe.ast_body());
   auto* expect = R"(Assignment{
@@ -11268,7 +11268,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto got = ToString(p->builder(), fe.ast_body());
   auto* expect = R"(Assignment{
@@ -11311,7 +11311,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto got = ToString(p->builder(), fe.ast_body());
   auto* expect = R"(Assignment{
@@ -11362,7 +11362,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto got = ToString(p->builder(), fe.ast_body());
   auto* expect = R"(Assignment{
@@ -11420,7 +11420,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto got = ToString(p->builder(), fe.ast_body());
   auto* expect = R"(Assignment{
@@ -11476,7 +11476,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto got = ToString(p->builder(), fe.ast_body());
   auto* expect = R"(Assignment{
@@ -11535,7 +11535,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -11596,7 +11596,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -11679,7 +11679,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -11774,7 +11774,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -11860,7 +11860,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto got = ToString(p->builder(), fe.ast_body());
   auto* expect = R"(Assignment{
@@ -11929,7 +11929,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto got = ToString(p->builder(), fe.ast_body());
   auto* expect = R"(Assignment{
@@ -11995,7 +11995,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -12069,7 +12069,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -12139,7 +12139,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto got = ToString(p->builder(), fe.ast_body());
   auto* expect = R"(Assignment{
@@ -12197,7 +12197,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto got = ToString(p->builder(), fe.ast_body());
   auto* expect = R"(Assignment{
@@ -12270,7 +12270,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto got = ToString(p->builder(), fe.ast_body());
   auto* expect = R"(Assignment{
@@ -12366,7 +12366,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto got = ToString(p->builder(), fe.ast_body());
   auto* expect = R"(Assignment{
@@ -12464,7 +12464,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(fe.EmitBody()) << p->error();
   EXPECT_THAT(
       p->error(),
@@ -12505,7 +12505,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto got = ToString(p->builder(), fe.ast_body());
   auto* expect = R"(Assignment{
@@ -12586,7 +12586,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto got = ToString(p->builder(), fe.ast_body());
   auto* expect = R"(Assignment{
@@ -12654,7 +12654,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto got = ToString(p->builder(), fe.ast_body());
   auto* expect = R"(Assignment{
@@ -12711,7 +12711,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto got = ToString(p->builder(), fe.ast_body());
   auto* expect = R"(Assignment{
@@ -12783,7 +12783,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto got = ToString(p->builder(), fe.ast_body());
   auto* expect = R"(Assignment{
@@ -12871,7 +12871,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto got = ToString(p->builder(), fe.ast_body());
   auto* expect = R"(Assignment{
@@ -12950,7 +12950,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto got = ToString(p->builder(), fe.ast_body());
   auto* expect = R"(Assignment{
@@ -13038,7 +13038,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto got = ToString(p->builder(), fe.ast_body());
   auto* expect = R"(Assignment{
@@ -13135,7 +13135,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto got = ToString(p->builder(), fe.ast_body());
   auto* expect = R"(Assignment{
@@ -13231,7 +13231,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto got = ToString(p->builder(), fe.ast_body());
   auto* expect = R"(Assignment{
@@ -13340,7 +13340,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto got = ToString(p->builder(), fe.ast_body());
   auto* expect = R"(Assignment{
@@ -13437,7 +13437,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto got = ToString(p->builder(), fe.ast_body());
   auto* expect = R"(Assignment{
@@ -13518,7 +13518,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto got = ToString(p->builder(), fe.ast_body());
   auto* expect = R"(Assignment{
@@ -13582,7 +13582,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto got = ToString(p->builder(), fe.ast_body());
   auto* expect = R"(Assignment{
@@ -13634,7 +13634,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(FlowClassifyCFGEdges(&fe));
   EXPECT_THAT(
       p->error(),
@@ -13666,7 +13666,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -13733,7 +13733,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(fe.EmitBody());
   // The weird forward branch pulls in 40 as part of the selection rather than
   // as a case.
@@ -13758,7 +13758,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto got = ToString(p->builder(), fe.ast_body());
   auto* expect = R"(Assignment{
@@ -13792,7 +13792,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(fe.EmitBody());
   EXPECT_THAT(p->error(),
               Eq("Control flow diverges at block 10 (to 20, 99) but it is not "
@@ -13813,7 +13813,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(fe.EmitBody());
   EXPECT_THAT(
       p->error(),
@@ -13849,7 +13849,7 @@
  OpFunctionEnd
    )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(fe.EmitBody());
   EXPECT_THAT(
       p->error(),
@@ -13884,7 +13884,7 @@
  OpFunctionEnd
    )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(fe.EmitBody());
   EXPECT_THAT(
       p->error(),
@@ -13901,7 +13901,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_EQ(fe.SiblingLoopConstruct(nullptr), nullptr);
 }
 
@@ -13916,7 +13916,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   ASSERT_TRUE(FlowLabelControlFlowConstructs(&fe)) << p->error();
   const Construct* c = fe.GetBlockInfo(10)->construct;
   EXPECT_NE(c, nullptr);
@@ -13941,7 +13941,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   ASSERT_TRUE(FlowLabelControlFlowConstructs(&fe)) << p->error();
   const Construct* c = fe.GetBlockInfo(20)->construct;
   EXPECT_EQ(c->kind, Construct::kContinue);
@@ -13970,7 +13970,7 @@
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions())
       << p->error() << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   ASSERT_TRUE(FlowLabelControlFlowConstructs(&fe)) << p->error();
   const Construct* c = fe.GetBlockInfo(20)->construct;
   EXPECT_EQ(c->kind, Construct::kContinue);
@@ -13998,7 +13998,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   ASSERT_TRUE(FlowLabelControlFlowConstructs(&fe)) << p->error();
   const Construct* c = fe.GetBlockInfo(30)->construct;
   EXPECT_EQ(c->kind, Construct::kContinue);
@@ -14038,7 +14038,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -14087,7 +14087,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto got = ToString(p->builder(), fe.ast_body());
   auto* expect = R"(Loop{
@@ -14129,7 +14129,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto got = ToString(p->builder(), fe.ast_body());
   auto* expect = R"(Switch{
@@ -14184,7 +14184,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto got = ToString(p->builder(), fe.ast_body());
   auto* expect = R"(Loop{
@@ -14236,7 +14236,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto got = ToString(p->builder(), fe.ast_body());
   auto* expect = R"(Loop{
@@ -14282,7 +14282,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto got = ToString(p->builder(), fe.ast_body());
   auto* expect = R"(Switch{
@@ -14344,7 +14344,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto got = ToString(p->builder(), fe.ast_body());
   auto* expect = R"(Assignment{
diff --git a/src/reader/spirv/function_composite_test.cc b/src/reader/spirv/function_composite_test.cc
index 89fa243..b2db5e7 100644
--- a/src/reader/spirv/function_composite_test.cc
+++ b/src/reader/spirv/function_composite_test.cc
@@ -85,7 +85,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()),
               HasSubstr(R"(VariableDeclStatement{
@@ -142,7 +142,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(
   VariableConst{
@@ -182,7 +182,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(
   VariableConst{
@@ -212,7 +212,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(
   VariableConst{
@@ -246,7 +246,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(
   VariableConst{
@@ -276,7 +276,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(fe.EmitBody());
   EXPECT_THAT(p->error(), Eq("OpCompositeExtract %1 index value 900 is out of "
                              "bounds for vector of 2 elements"));
@@ -296,7 +296,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(
   VariableConst{
@@ -326,7 +326,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(fe.EmitBody()) << p->error();
   EXPECT_THAT(p->error(), Eq("OpCompositeExtract %2 index value 3 is out of "
                              "bounds for matrix of 3 elements"));
@@ -346,7 +346,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(
   VariableConst{
@@ -379,7 +379,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(
   VariableConst{
@@ -410,7 +410,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(fe.EmitBody()) << p->error();
   EXPECT_THAT(p->error(),
               HasSubstr("can't do OpCompositeExtract on a runtime array: "));
@@ -430,7 +430,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(
   VariableConst{
@@ -471,7 +471,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto got = fe.ast_body();
   EXPECT_THAT(ToString(p->builder(), got), HasSubstr(R"(
@@ -516,7 +516,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(fe.EmitBody());
   EXPECT_THAT(p->error(), Eq("OpCompositeExtract %2 index value 40 is out of "
                              "bounds for structure %26 having 3 members"));
@@ -538,7 +538,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(
   VariableConst{
@@ -575,7 +575,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto body_str = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(body_str, HasSubstr(R"(VariableDeclStatement{
@@ -621,7 +621,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(fe.EmitBody());
   EXPECT_THAT(p->error(), Eq("OpCompositeInsert %1 index value 900 is out of "
                              "bounds for vector of 2 elements"));
@@ -641,7 +641,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto body_str = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(body_str, HasSubstr(R"(VariableDeclStatement{
@@ -691,7 +691,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(fe.EmitBody()) << p->error();
   EXPECT_THAT(p->error(), Eq("OpCompositeInsert %2 index value 3 is out of "
                              "bounds for matrix of 3 elements"));
@@ -711,7 +711,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto body_str = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(body_str, HasSubstr(R"(VariableDeclStatement{
@@ -761,7 +761,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto body_str = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(body_str, HasSubstr(R"(VariableDeclStatement{
@@ -808,7 +808,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(fe.EmitBody()) << p->error();
   EXPECT_THAT(p->error(),
               HasSubstr("can't do OpCompositeInsert on a runtime array: "));
@@ -828,7 +828,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto body_str = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(body_str, HasSubstr(R"(VariableDeclStatement{
@@ -902,7 +902,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto body_str = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(body_str, HasSubstr(R"(VariableDeclStatement{
@@ -1037,7 +1037,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(fe.EmitBody());
   EXPECT_THAT(p->error(), Eq("OpCompositeInsert %2 index value 40 is out of "
                              "bounds for structure %26 having 3 members"));
@@ -1059,7 +1059,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto body_str = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(body_str, HasSubstr(R"(VariableDeclStatement{
@@ -1130,7 +1130,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()),
               HasSubstr(R"(VariableDeclStatement{
@@ -1169,7 +1169,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()),
               HasSubstr(R"(VariableDeclStatement{
@@ -1210,7 +1210,7 @@
 
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{
     x_10
@@ -1252,7 +1252,7 @@
 
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{
     x_10
@@ -1310,7 +1310,7 @@
 
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{
     x_10
@@ -1340,7 +1340,7 @@
 
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(fe.EmitBody()) << p->error();
   EXPECT_THAT(p->error(),
               Eq("invalid vectorshuffle ID %10: index too large: 9"));
@@ -1361,7 +1361,7 @@
 
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   const auto got = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(got, HasSubstr(R"(VariableConst{
@@ -1391,7 +1391,7 @@
 
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   const auto got = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(got, HasSubstr(R"(VariableConst{
@@ -1424,7 +1424,7 @@
 
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   const auto got = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(got, HasSubstr(R"(
diff --git a/src/reader/spirv/function_conversion_test.cc b/src/reader/spirv/function_conversion_test.cc
index dd0728d..e92d9d1 100644
--- a/src/reader/spirv/function_conversion_test.cc
+++ b/src/reader/spirv/function_conversion_test.cc
@@ -76,7 +76,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(
   VariableConst{
@@ -101,7 +101,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(
   VariableConst{
@@ -130,7 +130,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(fe.EmitBody());
   EXPECT_THAT(p->error(),
               HasSubstr("unhandled expression for ID 2\n%2 = OpTypeVoid"));
@@ -146,7 +146,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(fe.EmitBody());
   EXPECT_THAT(p->error(),
               HasSubstr("unhandled expression for ID 2\n%2 = OpTypeVoid"));
@@ -162,7 +162,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(fe.EmitBody());
   EXPECT_THAT(p->error(),
               HasSubstr("unhandled expression for ID 2\n%2 = OpTypeVoid"));
@@ -178,7 +178,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(fe.EmitBody());
   EXPECT_THAT(p->error(),
               HasSubstr("unhandled expression for ID 2\n%2 = OpTypeVoid"));
@@ -194,7 +194,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(fe.EmitBody());
   EXPECT_THAT(p->error(),
               HasSubstr("operand for conversion to floating point must be "
@@ -211,7 +211,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(fe.EmitBody());
   EXPECT_THAT(
       p->error(),
@@ -230,7 +230,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{
     x_1
@@ -256,7 +256,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{
     x_1
@@ -284,7 +284,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{
     x_1
@@ -310,7 +310,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{
     x_1
@@ -337,7 +337,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(fe.EmitBody());
   EXPECT_THAT(p->error(), Eq("operand for conversion to floating point must be "
                              "integral scalar or vector, but got: __bool"));
@@ -353,7 +353,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(fe.EmitBody());
   EXPECT_THAT(p->error(),
               Eq("operand for conversion to floating point must be integral "
@@ -371,7 +371,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{
     x_1
@@ -399,7 +399,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{
     x_1
@@ -425,7 +425,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{
     x_1
@@ -453,7 +453,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{
     x_1
@@ -478,7 +478,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(fe.EmitBody());
   EXPECT_THAT(p->error(),
               Eq("operand for conversion to signed integer must be floating "
@@ -495,7 +495,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(fe.EmitBody());
   EXPECT_THAT(p->error(),
               Eq("operand for conversion to signed integer must be floating "
@@ -513,7 +513,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{
     x_1
@@ -539,7 +539,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{
     x_1
@@ -567,7 +567,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{
     x_1
@@ -593,7 +593,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{
     x_1
@@ -620,7 +620,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(fe.EmitBody());
   EXPECT_THAT(p->error(),
               Eq("operand for conversion to unsigned integer must be floating "
@@ -637,7 +637,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(fe.EmitBody());
   EXPECT_THAT(p->error(),
               Eq("operand for conversion to unsigned integer must be floating "
@@ -655,7 +655,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{
     x_1
@@ -683,7 +683,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{
     x_1
@@ -709,7 +709,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{
     x_1
@@ -737,7 +737,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{
     x_1
diff --git a/src/reader/spirv/function_decl_test.cc b/src/reader/spirv/function_decl_test.cc
index 420e520..cb38e8f 100644
--- a/src/reader/spirv/function_decl_test.cc
+++ b/src/reader/spirv/function_decl_test.cc
@@ -53,7 +53,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.Emit());
   auto got = p->program().to_str();
   std::string expect = R"(Module{
@@ -76,7 +76,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.Emit());
 
   auto got = p->program().to_str();
@@ -108,7 +108,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.Emit());
 
   auto got = p->program().to_str();
@@ -152,7 +152,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.Emit());
 
   auto got = p->program().to_str();
diff --git a/src/reader/spirv/function_glsl_std_450_test.cc b/src/reader/spirv/function_glsl_std_450_test.cc
index da3b7b0..3a44c0d 100644
--- a/src/reader/spirv/function_glsl_std_450_test.cc
+++ b/src/reader/spirv/function_glsl_std_450_test.cc
@@ -181,7 +181,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   const auto body = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(body, HasSubstr(R"(
@@ -212,7 +212,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   const auto body = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(body, HasSubstr(R"(
@@ -243,7 +243,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   const auto body = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(body, HasSubstr(R"(
@@ -275,7 +275,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   const auto body = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(body, HasSubstr(R"(
@@ -307,7 +307,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   const auto body = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(body, HasSubstr(R"(
@@ -338,7 +338,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   const auto body = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(body, HasSubstr(R"(
@@ -369,7 +369,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   const auto body = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(body, HasSubstr(R"(
@@ -401,7 +401,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   const auto body = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(body, HasSubstr(R"(
@@ -433,7 +433,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   const auto body = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(body, HasSubstr(R"(
@@ -467,7 +467,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   const auto body = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(body, HasSubstr(R"(
@@ -500,7 +500,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   const auto body = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(body, HasSubstr(R"(
@@ -533,7 +533,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   const auto body = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(body, HasSubstr(R"(
@@ -565,7 +565,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   const auto body = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(body, HasSubstr(R"(
@@ -598,7 +598,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   const auto body = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(body, HasSubstr(R"(
@@ -631,7 +631,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   const auto body = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(body, HasSubstr(R"(
@@ -738,7 +738,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   const auto body = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(body, HasSubstr(R"(
@@ -770,7 +770,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   const auto body = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(body, HasSubstr(R"(
@@ -802,7 +802,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   const auto body = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(body, HasSubstr(R"(
@@ -835,7 +835,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   const auto body = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(body, HasSubstr(R"(
@@ -868,7 +868,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   const auto body = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(body, HasSubstr(R"(
@@ -902,7 +902,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   const auto body = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(body, HasSubstr(R"(
@@ -948,7 +948,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   const auto body = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(body, HasSubstr(R"(
@@ -981,7 +981,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   const auto body = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(body, HasSubstr(R"(
@@ -1013,7 +1013,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   const auto body = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(body, HasSubstr(R"(
@@ -1047,7 +1047,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   const auto body = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(body, HasSubstr(R"(
@@ -1092,7 +1092,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   const auto body = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(body, HasSubstr(R"(
@@ -1144,7 +1144,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto body = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(body, HasSubstr(R"(
@@ -1202,7 +1202,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto body = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(body, HasSubstr(R"(
@@ -1260,7 +1260,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto body = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(body, HasSubstr(R"(
@@ -1320,7 +1320,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto body = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(body, HasSubstr(R"(
@@ -1378,7 +1378,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto body = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(body, HasSubstr(R"(
@@ -1436,7 +1436,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   auto body = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(body, HasSubstr(R"(
@@ -1512,7 +1512,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   const auto body = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(body, HasSubstr(R"(
@@ -1556,7 +1556,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   const auto body = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(body, HasSubstr(R"(
diff --git a/src/reader/spirv/function_logical_test.cc b/src/reader/spirv/function_logical_test.cc
index 1cc9917..6c4cf61 100644
--- a/src/reader/spirv/function_logical_test.cc
+++ b/src/reader/spirv/function_logical_test.cc
@@ -200,7 +200,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(
   VariableConst{
@@ -226,7 +226,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(
   VariableConst{
@@ -280,7 +280,7 @@
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions())
       << p->error() << "\n"
       << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   std::ostringstream ss;
   ss << R"(VariableConst{
@@ -718,7 +718,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(
   VariableConst{
@@ -748,7 +748,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(
   VariableConst{
@@ -786,7 +786,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(
   VariableConst{
@@ -816,7 +816,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(
   VariableConst{
@@ -854,7 +854,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(
   VariableConst{
@@ -884,7 +884,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(
   VariableConst{
@@ -922,7 +922,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(
   VariableConst{
@@ -952,7 +952,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(
   VariableConst{
@@ -990,7 +990,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(
   VariableConst{
@@ -1020,7 +1020,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(
   VariableConst{
@@ -1058,7 +1058,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(
   VariableConst{
@@ -1088,7 +1088,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(
   VariableConst{
@@ -1126,7 +1126,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()),
               HasSubstr(R"(VariableDeclStatement{
@@ -1158,7 +1158,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()),
               HasSubstr(R"(VariableDeclStatement{
@@ -1190,7 +1190,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()),
               HasSubstr(R"(VariableDeclStatement{
@@ -1222,7 +1222,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()),
               HasSubstr(R"(VariableDeclStatement{
@@ -1262,7 +1262,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()),
               HasSubstr(R"(VariableDeclStatement{
@@ -1308,7 +1308,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()),
               HasSubstr(R"(VariableDeclStatement{
@@ -1342,7 +1342,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()),
               HasSubstr(R"(VariableDeclStatement{
@@ -1376,7 +1376,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()),
               HasSubstr(R"(VariableDeclStatement{
@@ -1406,7 +1406,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()),
               HasSubstr(R"(VariableDeclStatement{
@@ -1440,7 +1440,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()),
               HasSubstr(R"(VariableDeclStatement{
@@ -1470,7 +1470,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()),
               HasSubstr(R"(VariableDeclStatement{
diff --git a/src/reader/spirv/function_memory_test.cc b/src/reader/spirv/function_memory_test.cc
index 2870f5a..85d7d9b 100644
--- a/src/reader/spirv/function_memory_test.cc
+++ b/src/reader/spirv/function_memory_test.cc
@@ -44,7 +44,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(Assignment{
   Identifier[not set]{x_1}
@@ -76,7 +76,7 @@
      OpReturn
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody());
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(Assignment{
   Identifier[not set]{x_1}
@@ -104,7 +104,7 @@
      OpReturn
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody());
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(Assignment{
   Identifier[not set]{x_1}
@@ -132,7 +132,7 @@
      OpReturn
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody());
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(Assignment{
   Identifier[not set]{x_1}
@@ -161,7 +161,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(
   VariableConst{
@@ -190,7 +190,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()),
               HasSubstr(R"(VariableDeclStatement{
@@ -232,7 +232,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()),
               HasSubstr(R"(VariableDeclStatement{
@@ -270,7 +270,7 @@
      OpReturn
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody());
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(Assignment{
   Identifier[not set]{x_1}
@@ -337,7 +337,7 @@
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions())
       << assembly << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody());
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(Assignment{
   MemberAccessor[not set]{
@@ -370,7 +370,7 @@
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions())
       << assembly << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(fe.EmitBody());
   EXPECT_THAT(p->error(), Eq("Access chain %2 index %42 value 42 is out of "
                              "bounds for vector of 4 elements"));
@@ -400,7 +400,7 @@
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions())
       << assembly << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody());
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(Assignment{
   ArrayAccessor[not set]{
@@ -437,7 +437,7 @@
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions())
       << assembly << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody());
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(Assignment{
   ArrayAccessor[not set]{
@@ -480,7 +480,7 @@
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions())
       << assembly << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody());
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(Assignment{
   ArrayAccessor[not set]{
@@ -522,7 +522,7 @@
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions())
       << assembly << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody());
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(Assignment{
   MemberAccessor[not set]{
@@ -570,7 +570,7 @@
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions())
       << assembly << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody());
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(Assignment{
   MemberAccessor[not set]{
@@ -616,7 +616,7 @@
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions())
       << assembly << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(fe.EmitBody());
   EXPECT_THAT(p->error(), Eq("Access chain %2 index %10 is a non-constant "
                              "index into a structure %55"));
@@ -647,7 +647,7 @@
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions())
       << assembly << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(fe.EmitBody());
   EXPECT_THAT(p->error(), Eq("Access chain %2 index value 99 is out of bounds "
                              "for structure %55 having 2 members"));
@@ -680,7 +680,7 @@
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions())
       << assembly << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody());
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(Assignment{
   ArrayAccessor[not set]{
@@ -720,7 +720,7 @@
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions())
       << assembly << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody());
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(Assignment{
   MemberAccessor[not set]{
@@ -755,7 +755,7 @@
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions())
       << assembly << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_FALSE(fe.EmitBody());
   EXPECT_THAT(p->error(),
               HasSubstr("Access chain with unknown or invalid pointee type "
@@ -828,7 +828,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModule()) << assembly << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   const auto got = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(got, HasSubstr(R"(Assignment{
@@ -870,7 +870,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModule()) << assembly << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   const auto got = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(got, HasSubstr(R"(Assignment{
@@ -910,7 +910,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModule()) << assembly << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(Assignment{
   ArrayAccessor[not set]{
@@ -942,7 +942,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModule()) << assembly << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()),
               HasSubstr(R"(VariableDeclStatement{
@@ -997,7 +997,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModule()) << assembly << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_EQ(ToString(p->builder(), fe.ast_body()),
             R"(VariableDeclStatement{
@@ -1084,7 +1084,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModule()) << assembly << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   const auto body_str = ToString(p->builder(), fe.ast_body());
   EXPECT_THAT(body_str, HasSubstr(R"(VariableDeclStatement{
diff --git a/src/reader/spirv/function_misc_test.cc b/src/reader/spirv/function_misc_test.cc
index b523d8b..5f4a197 100644
--- a/src/reader/spirv/function_misc_test.cc
+++ b/src/reader/spirv/function_misc_test.cc
@@ -62,7 +62,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()),
               HasSubstr(R"(VariableDeclStatement{
@@ -126,7 +126,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()),
               HasSubstr(R"(VariableDeclStatement{
@@ -205,7 +205,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()),
               HasSubstr(R"(VariableDeclStatement{
@@ -266,7 +266,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()),
               HasSubstr(R"(VariableDeclStatement{
@@ -327,7 +327,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()),
               HasSubstr(R"(VariableDeclStatement{
@@ -369,7 +369,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()),
               HasSubstr(R"(VariableDeclStatement{
@@ -402,7 +402,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()),
               HasSubstr(R"(VariableDeclStatement{
@@ -434,7 +434,7 @@
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions())
       << p->error() << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()), Eq(R"(Return{}
 )"));
@@ -460,7 +460,7 @@
 )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
 
   auto* result = fe.Swizzle(GetParam().index);
   if (GetParam().expected_error.empty()) {
diff --git a/src/reader/spirv/function_var_test.cc b/src/reader/spirv/function_var_test.cc
index 7bf5b0e..a66e851 100644
--- a/src/reader/spirv/function_var_test.cc
+++ b/src/reader/spirv/function_var_test.cc
@@ -84,7 +84,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitFunctionVariables());
 
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()),
@@ -123,7 +123,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitFunctionVariables());
 
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()),
@@ -162,7 +162,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitFunctionVariables());
 
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()),
@@ -204,7 +204,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitFunctionVariables());
 
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()),
@@ -278,7 +278,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitFunctionVariables());
 
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()),
@@ -338,7 +338,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitFunctionVariables());
 
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()),
@@ -377,7 +377,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitFunctionVariables());
 
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()),
@@ -424,7 +424,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitFunctionVariables());
 
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()),
@@ -459,7 +459,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitFunctionVariables());
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -494,7 +494,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitFunctionVariables());
 
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()),
@@ -529,7 +529,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitFunctionVariables());
 
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()),
@@ -564,7 +564,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitFunctionVariables());
 
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()),
@@ -604,7 +604,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitFunctionVariables());
 
   EXPECT_THAT(ToString(p->builder(), fe.ast_body()),
@@ -649,7 +649,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -697,7 +697,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -769,7 +769,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -868,7 +868,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -984,7 +984,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   // We don't hoist x_1 into its own mutable variable. It is emitted as
@@ -1071,7 +1071,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -1158,7 +1158,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -1239,7 +1239,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   // We don't hoist x_1 into its own mutable variable. It is emitted as
@@ -1315,7 +1315,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -1459,7 +1459,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -1617,7 +1617,7 @@
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions())
       << assembly << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -1786,7 +1786,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -1908,7 +1908,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -2032,7 +2032,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
@@ -2122,7 +2122,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
 
   auto got = ToString(p->builder(), fe.ast_body());
diff --git a/src/reader/spirv/parser_impl.h b/src/reader/spirv/parser_impl.h
index 0c147d3..325c750 100644
--- a/src/reader/spirv/parser_impl.h
+++ b/src/reader/spirv/parser_impl.h
@@ -537,6 +537,9 @@
     return function_to_ep_info_[entry_point];
   }
 
+  /// Returns the SPIR-V binary.
+  const std::vector<uint32_t>& spv_binary() { return spv_binary_; }
+
  private:
   /// Converts a specific SPIR-V type to a Tint type. Integer case
   typ::Type ConvertType(const spvtools::opt::analysis::Integer* int_ty);
diff --git a/src/reader/spirv/parser_impl_convert_type_test.cc b/src/reader/spirv/parser_impl_convert_type_test.cc
index 088cbe4..2249277 100644
--- a/src/reader/spirv/parser_impl_convert_type_test.cc
+++ b/src/reader/spirv/parser_impl_convert_type_test.cc
@@ -26,14 +26,14 @@
 TEST_F(SpvParserTest, ConvertType_PreservesExistingFailure) {
   auto p = parser(std::vector<uint32_t>{});
   p->Fail() << "boing";
-  auto type = p->ConvertType(10);
+  auto* type = p->ConvertType(10);
   EXPECT_EQ(type, nullptr);
   EXPECT_THAT(p->error(), Eq("boing"));
 }
 
 TEST_F(SpvParserTest, ConvertType_RequiresInternalRepresntation) {
   auto p = parser(std::vector<uint32_t>{});
-  auto type = p->ConvertType(10);
+  auto* type = p->ConvertType(10);
   EXPECT_EQ(type, nullptr);
   EXPECT_THAT(
       p->error(),
@@ -44,7 +44,7 @@
   auto p = parser(test::Assemble("%1 = OpExtInstImport \"GLSL.std.450\""));
   EXPECT_TRUE(p->BuildInternalModule());
 
-  auto type = p->ConvertType(10);
+  auto* type = p->ConvertType(10);
   EXPECT_EQ(type, nullptr);
   EXPECT_EQ(nullptr, type);
   EXPECT_THAT(p->error(), Eq("ID is not a SPIR-V type: 10"));
@@ -54,7 +54,7 @@
   auto p = parser(test::Assemble("%1 = OpExtInstImport \"GLSL.std.450\""));
   EXPECT_TRUE(p->BuildInternalModule());
 
-  auto type = p->ConvertType(1);
+  auto* type = p->ConvertType(1);
   EXPECT_EQ(nullptr, type);
   EXPECT_THAT(p->error(), Eq("ID is not a SPIR-V type: 1"));
 }
@@ -64,7 +64,7 @@
   auto p = parser(test::Assemble("%70 = OpTypePipe WriteOnly"));
   EXPECT_TRUE(p->BuildInternalModule());
 
-  auto type = p->ConvertType(70);
+  auto* type = p->ConvertType(70);
   EXPECT_EQ(nullptr, type);
   EXPECT_THAT(p->error(),
               Eq("unknown SPIR-V type with ID 70: %70 = OpTypePipe WriteOnly"));
@@ -74,7 +74,7 @@
   auto p = parser(test::Assemble("%1 = OpTypeVoid"));
   EXPECT_TRUE(p->BuildInternalModule());
 
-  auto type = p->ConvertType(1);
+  auto* type = p->ConvertType(1);
   EXPECT_TRUE(type->Is<sem::Void>());
   EXPECT_TRUE(p->error().empty());
 }
@@ -83,7 +83,7 @@
   auto p = parser(test::Assemble("%100 = OpTypeBool"));
   EXPECT_TRUE(p->BuildInternalModule());
 
-  auto type = p->ConvertType(100);
+  auto* type = p->ConvertType(100);
   EXPECT_TRUE(type->Is<sem::Bool>());
   EXPECT_TRUE(p->error().empty());
 }
@@ -92,7 +92,7 @@
   auto p = parser(test::Assemble("%2 = OpTypeInt 32 1"));
   EXPECT_TRUE(p->BuildInternalModule());
 
-  auto type = p->ConvertType(2);
+  auto* type = p->ConvertType(2);
   EXPECT_TRUE(type->Is<sem::I32>());
   EXPECT_TRUE(p->error().empty());
 }
@@ -101,7 +101,7 @@
   auto p = parser(test::Assemble("%3 = OpTypeInt 32 0"));
   EXPECT_TRUE(p->BuildInternalModule());
 
-  auto type = p->ConvertType(3);
+  auto* type = p->ConvertType(3);
   EXPECT_TRUE(type->Is<sem::U32>());
   EXPECT_TRUE(p->error().empty());
 }
@@ -110,7 +110,7 @@
   auto p = parser(test::Assemble("%4 = OpTypeFloat 32"));
   EXPECT_TRUE(p->BuildInternalModule());
 
-  auto type = p->ConvertType(4);
+  auto* type = p->ConvertType(4);
   EXPECT_TRUE(type->Is<sem::F32>());
   EXPECT_TRUE(p->error().empty());
 }
@@ -119,7 +119,7 @@
   auto p = parser(test::Assemble("%5 = OpTypeInt 17 1"));
   EXPECT_TRUE(p->BuildInternalModule());
 
-  auto type = p->ConvertType(5);
+  auto* type = p->ConvertType(5);
   EXPECT_EQ(type, nullptr);
   EXPECT_THAT(p->error(), Eq("unhandled integer width: 17"));
 }
@@ -128,7 +128,7 @@
   auto p = parser(test::Assemble("%6 = OpTypeFloat 19"));
   EXPECT_TRUE(p->BuildInternalModule());
 
-  auto type = p->ConvertType(6);
+  auto* type = p->ConvertType(6);
   EXPECT_EQ(type, nullptr);
   EXPECT_THAT(p->error(), Eq("unhandled float width: 19"));
 }
@@ -140,7 +140,7 @@
   )"));
   EXPECT_TRUE(p->BuildInternalModule());
 
-  auto type = p->ConvertType(20);
+  auto* type = p->ConvertType(20);
   EXPECT_EQ(type, nullptr);
   EXPECT_THAT(p->error(), Eq("unknown SPIR-V type: 5"));
 }
@@ -154,17 +154,17 @@
   )"));
   EXPECT_TRUE(p->BuildInternalModule());
 
-  auto v2xf32 = p->ConvertType(20);
+  auto* v2xf32 = p->ConvertType(20);
   EXPECT_TRUE(v2xf32->Is<sem::Vector>());
   EXPECT_TRUE(v2xf32->As<sem::Vector>()->type()->Is<sem::F32>());
   EXPECT_EQ(v2xf32->As<sem::Vector>()->size(), 2u);
 
-  auto v3xf32 = p->ConvertType(30);
+  auto* v3xf32 = p->ConvertType(30);
   EXPECT_TRUE(v3xf32->Is<sem::Vector>());
   EXPECT_TRUE(v3xf32->As<sem::Vector>()->type()->Is<sem::F32>());
   EXPECT_EQ(v3xf32->As<sem::Vector>()->size(), 3u);
 
-  auto v4xf32 = p->ConvertType(40);
+  auto* v4xf32 = p->ConvertType(40);
   EXPECT_TRUE(v4xf32->Is<sem::Vector>());
   EXPECT_TRUE(v4xf32->As<sem::Vector>()->type()->Is<sem::F32>());
   EXPECT_EQ(v4xf32->As<sem::Vector>()->size(), 4u);
@@ -181,17 +181,17 @@
   )"));
   EXPECT_TRUE(p->BuildInternalModule());
 
-  auto v2xi32 = p->ConvertType(20);
+  auto* v2xi32 = p->ConvertType(20);
   EXPECT_TRUE(v2xi32->Is<sem::Vector>());
   EXPECT_TRUE(v2xi32->As<sem::Vector>()->type()->Is<sem::I32>());
   EXPECT_EQ(v2xi32->As<sem::Vector>()->size(), 2u);
 
-  auto v3xi32 = p->ConvertType(30);
+  auto* v3xi32 = p->ConvertType(30);
   EXPECT_TRUE(v3xi32->Is<sem::Vector>());
   EXPECT_TRUE(v3xi32->As<sem::Vector>()->type()->Is<sem::I32>());
   EXPECT_EQ(v3xi32->As<sem::Vector>()->size(), 3u);
 
-  auto v4xi32 = p->ConvertType(40);
+  auto* v4xi32 = p->ConvertType(40);
   EXPECT_TRUE(v4xi32->Is<sem::Vector>());
   EXPECT_TRUE(v4xi32->As<sem::Vector>()->type()->Is<sem::I32>());
   EXPECT_EQ(v4xi32->As<sem::Vector>()->size(), 4u);
@@ -208,17 +208,17 @@
   )"));
   EXPECT_TRUE(p->BuildInternalModule());
 
-  auto v2xu32 = p->ConvertType(20);
+  auto* v2xu32 = p->ConvertType(20);
   EXPECT_TRUE(v2xu32->Is<sem::Vector>());
   EXPECT_TRUE(v2xu32->As<sem::Vector>()->type()->Is<sem::U32>());
   EXPECT_EQ(v2xu32->As<sem::Vector>()->size(), 2u);
 
-  auto v3xu32 = p->ConvertType(30);
+  auto* v3xu32 = p->ConvertType(30);
   EXPECT_TRUE(v3xu32->Is<sem::Vector>());
   EXPECT_TRUE(v3xu32->As<sem::Vector>()->type()->Is<sem::U32>());
   EXPECT_EQ(v3xu32->As<sem::Vector>()->size(), 3u);
 
-  auto v4xu32 = p->ConvertType(40);
+  auto* v4xu32 = p->ConvertType(40);
   EXPECT_TRUE(v4xu32->Is<sem::Vector>());
   EXPECT_TRUE(v4xu32->As<sem::Vector>()->type()->Is<sem::U32>());
   EXPECT_EQ(v4xu32->As<sem::Vector>()->size(), 4u);
@@ -234,7 +234,7 @@
   )"));
   EXPECT_TRUE(p->BuildInternalModule());
 
-  auto type = p->ConvertType(20);
+  auto* type = p->ConvertType(20);
   EXPECT_EQ(type, nullptr);
   EXPECT_THAT(p->error(), Eq("unknown SPIR-V type: 5"));
 }
@@ -260,55 +260,55 @@
   )"));
   EXPECT_TRUE(p->BuildInternalModule());
 
-  auto m22 = p->ConvertType(22);
+  auto* m22 = p->ConvertType(22);
   EXPECT_TRUE(m22->Is<sem::Matrix>());
   EXPECT_TRUE(m22->As<sem::Matrix>()->type()->Is<sem::F32>());
   EXPECT_EQ(m22->As<sem::Matrix>()->rows(), 2u);
   EXPECT_EQ(m22->As<sem::Matrix>()->columns(), 2u);
 
-  auto m23 = p->ConvertType(23);
+  auto* m23 = p->ConvertType(23);
   EXPECT_TRUE(m23->Is<sem::Matrix>());
   EXPECT_TRUE(m23->As<sem::Matrix>()->type()->Is<sem::F32>());
   EXPECT_EQ(m23->As<sem::Matrix>()->rows(), 2u);
   EXPECT_EQ(m23->As<sem::Matrix>()->columns(), 3u);
 
-  auto m24 = p->ConvertType(24);
+  auto* m24 = p->ConvertType(24);
   EXPECT_TRUE(m24->Is<sem::Matrix>());
   EXPECT_TRUE(m24->As<sem::Matrix>()->type()->Is<sem::F32>());
   EXPECT_EQ(m24->As<sem::Matrix>()->rows(), 2u);
   EXPECT_EQ(m24->As<sem::Matrix>()->columns(), 4u);
 
-  auto m32 = p->ConvertType(32);
+  auto* m32 = p->ConvertType(32);
   EXPECT_TRUE(m32->Is<sem::Matrix>());
   EXPECT_TRUE(m32->As<sem::Matrix>()->type()->Is<sem::F32>());
   EXPECT_EQ(m32->As<sem::Matrix>()->rows(), 3u);
   EXPECT_EQ(m32->As<sem::Matrix>()->columns(), 2u);
 
-  auto m33 = p->ConvertType(33);
+  auto* m33 = p->ConvertType(33);
   EXPECT_TRUE(m33->Is<sem::Matrix>());
   EXPECT_TRUE(m33->As<sem::Matrix>()->type()->Is<sem::F32>());
   EXPECT_EQ(m33->As<sem::Matrix>()->rows(), 3u);
   EXPECT_EQ(m33->As<sem::Matrix>()->columns(), 3u);
 
-  auto m34 = p->ConvertType(34);
+  auto* m34 = p->ConvertType(34);
   EXPECT_TRUE(m34->Is<sem::Matrix>());
   EXPECT_TRUE(m34->As<sem::Matrix>()->type()->Is<sem::F32>());
   EXPECT_EQ(m34->As<sem::Matrix>()->rows(), 3u);
   EXPECT_EQ(m34->As<sem::Matrix>()->columns(), 4u);
 
-  auto m42 = p->ConvertType(42);
+  auto* m42 = p->ConvertType(42);
   EXPECT_TRUE(m42->Is<sem::Matrix>());
   EXPECT_TRUE(m42->As<sem::Matrix>()->type()->Is<sem::F32>());
   EXPECT_EQ(m42->As<sem::Matrix>()->rows(), 4u);
   EXPECT_EQ(m42->As<sem::Matrix>()->columns(), 2u);
 
-  auto m43 = p->ConvertType(43);
+  auto* m43 = p->ConvertType(43);
   EXPECT_TRUE(m43->Is<sem::Matrix>());
   EXPECT_TRUE(m43->As<sem::Matrix>()->type()->Is<sem::F32>());
   EXPECT_EQ(m43->As<sem::Matrix>()->rows(), 4u);
   EXPECT_EQ(m43->As<sem::Matrix>()->columns(), 3u);
 
-  auto m44 = p->ConvertType(44);
+  auto* m44 = p->ConvertType(44);
   EXPECT_TRUE(m44->Is<sem::Matrix>());
   EXPECT_TRUE(m44->As<sem::Matrix>()->type()->Is<sem::F32>());
   EXPECT_EQ(m44->As<sem::Matrix>()->rows(), 4u);
@@ -324,7 +324,7 @@
   )"));
   EXPECT_TRUE(p->BuildInternalModule());
 
-  auto type = p->ConvertType(10);
+  auto* type = p->ConvertType(10);
   ASSERT_NE(type, nullptr);
   EXPECT_TRUE(type->UnwrapAliasIfNeeded()->Is<sem::ArrayType>());
   auto* arr_type = type->UnwrapAliasIfNeeded()->As<sem::ArrayType>();
@@ -345,7 +345,7 @@
     %10 = OpTypeRuntimeArray %uint
   )"));
   EXPECT_TRUE(p->BuildInternalModule());
-  auto type = p->ConvertType(10);
+  auto* type = p->ConvertType(10);
   EXPECT_EQ(type, nullptr);
   EXPECT_THAT(
       p->error(),
@@ -359,7 +359,7 @@
     %10 = OpTypeRuntimeArray %uint
   )"));
   EXPECT_TRUE(p->BuildInternalModule());
-  auto type = p->ConvertType(10);
+  auto* type = p->ConvertType(10);
   ASSERT_NE(type, nullptr);
   auto* arr_type = type->UnwrapAliasIfNeeded()->As<sem::ArrayType>();
   EXPECT_TRUE(arr_type->IsRuntimeArray());
@@ -378,7 +378,7 @@
     %10 = OpTypeRuntimeArray %uint
   )"));
   EXPECT_TRUE(p->BuildInternalModule());
-  auto type = p->ConvertType(10);
+  auto* type = p->ConvertType(10);
   EXPECT_EQ(type, nullptr);
   EXPECT_THAT(p->error(),
               Eq("invalid array type ID 10: ArrayStride can't be 0"));
@@ -393,7 +393,7 @@
     %10 = OpTypeRuntimeArray %uint
   )"));
   EXPECT_TRUE(p->BuildInternalModule());
-  auto type = p->ConvertType(10);
+  auto* type = p->ConvertType(10);
   EXPECT_EQ(type, nullptr);
   EXPECT_THAT(p->error(),
               Eq("invalid array type ID 10: multiple ArrayStride decorations"));
@@ -407,7 +407,7 @@
   )"));
   EXPECT_TRUE(p->BuildInternalModule());
 
-  auto type = p->ConvertType(10);
+  auto* type = p->ConvertType(10);
   ASSERT_NE(type, nullptr);
   EXPECT_TRUE(type->Is<sem::ArrayType>());
   auto* arr_type = type->As<sem::ArrayType>();
@@ -430,7 +430,7 @@
   )"));
   EXPECT_TRUE(p->BuildInternalModule());
 
-  auto type = p->ConvertType(10);
+  auto* type = p->ConvertType(10);
   ASSERT_EQ(type, nullptr);
   EXPECT_THAT(p->error(),
               Eq("Array type 10 length is a specialization constant"));
@@ -445,7 +445,7 @@
   )"));
   EXPECT_TRUE(p->BuildInternalModule());
 
-  auto type = p->ConvertType(10);
+  auto* type = p->ConvertType(10);
   ASSERT_EQ(type, nullptr);
   EXPECT_THAT(p->error(),
               Eq("Array type 10 length is a specialization constant"));
@@ -463,7 +463,7 @@
   )"));
   EXPECT_TRUE(p->BuildInternalModule());
 
-  auto type = p->ConvertType(10);
+  auto* type = p->ConvertType(10);
   ASSERT_EQ(type, nullptr);
   // TODO(dneto): Right now it's rejected earlier in the flow because
   // we can't even utter the uint64 type.
@@ -478,7 +478,7 @@
     %10 = OpTypeArray %uint %uint_5
   )"));
   EXPECT_TRUE(p->BuildInternalModule());
-  auto type = p->ConvertType(10);
+  auto* type = p->ConvertType(10);
   EXPECT_EQ(type, nullptr);
   EXPECT_THAT(
       p->error(),
@@ -494,7 +494,7 @@
   )"));
   EXPECT_TRUE(p->BuildInternalModule());
 
-  auto type = p->ConvertType(10);
+  auto* type = p->ConvertType(10);
   ASSERT_NE(type, nullptr);
   EXPECT_TRUE(type->UnwrapAliasIfNeeded()->Is<sem::ArrayType>());
   auto* arr_type = type->UnwrapAliasIfNeeded()->As<sem::ArrayType>();
@@ -517,7 +517,7 @@
   )"));
   EXPECT_TRUE(p->BuildInternalModule());
 
-  auto type = p->ConvertType(10);
+  auto* type = p->ConvertType(10);
   ASSERT_EQ(type, nullptr);
   EXPECT_THAT(p->error(),
               Eq("invalid array type ID 10: ArrayStride can't be 0"));
@@ -533,7 +533,7 @@
   )"));
   EXPECT_TRUE(p->BuildInternalModule());
 
-  auto type = p->ConvertType(10);
+  auto* type = p->ConvertType(10);
   ASSERT_EQ(type, nullptr);
   EXPECT_THAT(p->error(),
               Eq("invalid array type ID 10: multiple ArrayStride decorations"));
@@ -548,7 +548,7 @@
   EXPECT_TRUE(p->BuildInternalModule());
   EXPECT_TRUE(p->RegisterUserAndStructMemberNames());
 
-  auto type = p->ConvertType(10);
+  auto* type = p->ConvertType(10);
   ASSERT_NE(type, nullptr);
   EXPECT_TRUE(type->Is<sem::StructType>());
 
@@ -569,7 +569,7 @@
   EXPECT_TRUE(p->BuildInternalModule());
   EXPECT_TRUE(p->RegisterUserAndStructMemberNames());
 
-  auto type = p->ConvertType(10);
+  auto* type = p->ConvertType(10);
   ASSERT_NE(type, nullptr);
   EXPECT_TRUE(type->Is<sem::StructType>());
 
@@ -594,7 +594,7 @@
   EXPECT_TRUE(p->BuildInternalModule());
   EXPECT_TRUE(p->RegisterUserAndStructMemberNames());
 
-  auto type = p->ConvertType(10);
+  auto* type = p->ConvertType(10);
   ASSERT_NE(type, nullptr);
   EXPECT_TRUE(type->Is<sem::StructType>());
 
@@ -621,7 +621,7 @@
   )"));
   EXPECT_TRUE(p->BuildInternalModule()) << p->error();
 
-  auto type = p->ConvertType(3);
+  auto* type = p->ConvertType(3);
   EXPECT_EQ(type, nullptr);
   EXPECT_THAT(p->error(),
               Eq("SPIR-V pointer type with ID 3 has invalid pointee type 42"));
@@ -644,7 +644,7 @@
   )"));
   EXPECT_TRUE(p->BuildInternalModule());
 
-  auto type = p->ConvertType(3);
+  auto* type = p->ConvertType(3);
   EXPECT_TRUE(type->Is<sem::Pointer>());
   auto* ptr_ty = type->As<sem::Pointer>();
   EXPECT_NE(ptr_ty, nullptr);
@@ -660,7 +660,7 @@
   )"));
   EXPECT_TRUE(p->BuildInternalModule());
 
-  auto type = p->ConvertType(3);
+  auto* type = p->ConvertType(3);
   EXPECT_TRUE(type->Is<sem::Pointer>());
   auto* ptr_ty = type->As<sem::Pointer>();
   EXPECT_NE(ptr_ty, nullptr);
@@ -676,7 +676,7 @@
   )"));
   EXPECT_TRUE(p->BuildInternalModule());
 
-  auto type = p->ConvertType(3);
+  auto* type = p->ConvertType(3);
   EXPECT_TRUE(type->Is<sem::Pointer>());
   auto* ptr_ty = type->As<sem::Pointer>();
   EXPECT_NE(ptr_ty, nullptr);
@@ -692,7 +692,7 @@
   )"));
   EXPECT_TRUE(p->BuildInternalModule());
 
-  auto type = p->ConvertType(3);
+  auto* type = p->ConvertType(3);
   EXPECT_TRUE(type->Is<sem::Pointer>());
   auto* ptr_ty = type->As<sem::Pointer>();
   EXPECT_NE(ptr_ty, nullptr);
@@ -708,7 +708,7 @@
   )"));
   EXPECT_TRUE(p->BuildInternalModule());
 
-  auto type = p->ConvertType(3);
+  auto* type = p->ConvertType(3);
   EXPECT_TRUE(type->Is<sem::Pointer>());
   auto* ptr_ty = type->As<sem::Pointer>();
   EXPECT_NE(ptr_ty, nullptr);
@@ -724,7 +724,7 @@
   )"));
   EXPECT_TRUE(p->BuildInternalModule());
 
-  auto type = p->ConvertType(3);
+  auto* type = p->ConvertType(3);
   EXPECT_TRUE(type->Is<sem::Pointer>());
   auto* ptr_ty = type->As<sem::Pointer>();
   EXPECT_NE(ptr_ty, nullptr);
@@ -740,7 +740,7 @@
   )"));
   EXPECT_TRUE(p->BuildInternalModule());
 
-  auto type = p->ConvertType(3);
+  auto* type = p->ConvertType(3);
   EXPECT_TRUE(type->Is<sem::Pointer>());
   auto* ptr_ty = type->As<sem::Pointer>();
   EXPECT_NE(ptr_ty, nullptr);
@@ -756,7 +756,7 @@
   )"));
   EXPECT_TRUE(p->BuildInternalModule());
 
-  auto type = p->ConvertType(3);
+  auto* type = p->ConvertType(3);
   EXPECT_TRUE(type->Is<sem::Pointer>());
   auto* ptr_ty = type->As<sem::Pointer>();
   EXPECT_NE(ptr_ty, nullptr);
@@ -772,7 +772,7 @@
   )"));
   EXPECT_TRUE(p->BuildInternalModule());
 
-  auto type = p->ConvertType(3);
+  auto* type = p->ConvertType(3);
   EXPECT_TRUE(type->Is<sem::Pointer>());
   auto* ptr_ty = type->As<sem::Pointer>();
   EXPECT_NE(ptr_ty, nullptr);
@@ -790,7 +790,7 @@
   )"));
   EXPECT_TRUE(p->BuildInternalModule());
 
-  auto type = p->ConvertType(3);
+  auto* type = p->ConvertType(3);
   EXPECT_NE(type, nullptr);
   EXPECT_TRUE(type->Is<sem::Pointer>());
 
@@ -814,7 +814,7 @@
   )"));
   EXPECT_TRUE(p->BuildInternalModule());
 
-  auto type = p->ConvertType(1);
+  auto* type = p->ConvertType(1);
   EXPECT_TRUE(type->Is<sem::Void>());
   EXPECT_TRUE(p->error().empty());
 }
@@ -827,7 +827,7 @@
   )"));
   EXPECT_TRUE(p->BuildInternalModule());
 
-  auto type = p->ConvertType(1);
+  auto* type = p->ConvertType(1);
   EXPECT_TRUE(type->Is<sem::Void>());
   EXPECT_TRUE(p->error().empty());
 }
@@ -840,7 +840,7 @@
   )"));
   EXPECT_TRUE(p->BuildInternalModule());
 
-  auto type = p->ConvertType(1);
+  auto* type = p->ConvertType(1);
   EXPECT_TRUE(type->Is<sem::Void>());
   EXPECT_TRUE(p->error().empty());
 }
diff --git a/src/reader/spirv/parser_impl_handle_test.cc b/src/reader/spirv/parser_impl_handle_test.cc
index 89c23e6..757d18b 100644
--- a/src/reader/spirv/parser_impl_handle_test.cc
+++ b/src/reader/spirv/parser_impl_handle_test.cc
@@ -4827,7 +4827,7 @@
     EXPECT_THAT(p->error(), StartsWith(GetParam().expected_error)) << assembly;
   } else {
     EXPECT_TRUE(p->error().empty()) << p->error();
-    FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+    auto fe = p->function_emitter(100);
     // We actually have to generate the module to cache expressions for the
     // result IDs, particularly the OpCopyObject
     fe.Emit();
@@ -5691,7 +5691,7 @@
   )";
   auto p = parser(test::Assemble(assembly));
   EXPECT_TRUE(p->BuildAndParseInternalModule()) << assembly;
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_TRUE(p->error().empty()) << p->error();
   const auto got = ToString(p->builder(), fe.ast_body());
diff --git a/src/reader/spirv/parser_impl_module_var_test.cc b/src/reader/spirv/parser_impl_module_var_test.cc
index bb5d9f4..03a6801 100644
--- a/src/reader/spirv/parser_impl_module_var_test.cc
+++ b/src/reader/spirv/parser_impl_module_var_test.cc
@@ -1999,7 +1999,7 @@
      OpFunctionEnd
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
-  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  auto fe = p->function_emitter(100);
   EXPECT_TRUE(fe.EmitBody()) << p->error();
   EXPECT_TRUE(p->error().empty());
 
diff --git a/src/reader/spirv/parser_impl_test_helper.h b/src/reader/spirv/parser_impl_test_helper.h
index 298012f..0d9dcc6 100644
--- a/src/reader/spirv/parser_impl_test_helper.h
+++ b/src/reader/spirv/parser_impl_test_helper.h
@@ -17,15 +17,102 @@
 
 #include <memory>
 #include <string>
+#include <unordered_set>
+#include <utility>
 #include <vector>
 
 #include "gtest/gtest.h"
+#include "source/opt/ir_context.h"
 #include "src/demangler.h"
+#include "src/reader/spirv/fail_stream.h"
+#include "src/reader/spirv/function.h"
+#include "src/reader/spirv/namer.h"
 #include "src/reader/spirv/parser_impl.h"
+#include "src/reader/spirv/usage.h"
 
 namespace tint {
 namespace reader {
 namespace spirv {
+namespace test {
+
+// A test class that wraps ParseImpl
+class ParserImplWrapperForTest {
+ public:
+  explicit ParserImplWrapperForTest(const std::vector<uint32_t>& input)
+      : impl_(input) {}
+
+  // Returns a new function emitter for the given function ID.
+  // Assumes ParserImpl::BuildInternalRepresentation has been run and
+  // succeeded.
+  FunctionEmitter function_emitter(uint32_t function_id) {
+    auto* spirv_function = impl_.ir_context()->GetFunction(function_id);
+    return FunctionEmitter(&impl_, *spirv_function);
+  }
+
+  // Forward methods used by tests to the real implementation.
+  bool Parse() { return impl_.Parse(); }
+  Program program() { return impl_.program(); }
+  Namer& namer() { return impl_.namer(); }
+  ProgramBuilder& builder() { return impl_.builder(); }
+  const std::string error() { return impl_.error(); }
+  FailStream& Fail() { return impl_.Fail(); }
+  spvtools::opt::IRContext* ir_context() { return impl_.ir_context(); }
+  bool BuildInternalModule() { return impl_.BuildInternalModule(); }
+  bool BuildAndParseInternalModuleExceptFunctions() {
+    return impl_.BuildAndParseInternalModuleExceptFunctions();
+  }
+  bool BuildAndParseInternalModule() {
+    return impl_.BuildAndParseInternalModule();
+  }
+  bool RegisterUserAndStructMemberNames() {
+    return impl_.RegisterUserAndStructMemberNames();
+  }
+  const std::unordered_set<uint32_t>& glsl_std_450_imports() const {
+    return impl_.glsl_std_450_imports();
+  }
+  sem::Type* ConvertType(uint32_t id) { return impl_.ConvertType(id); }
+  DecorationList GetDecorationsFor(uint32_t id) const {
+    return impl_.GetDecorationsFor(id);
+  }
+  DecorationList GetDecorationsForMember(uint32_t id,
+                                         uint32_t member_index) const {
+    return impl_.GetDecorationsForMember(id, member_index);
+  }
+  ast::Decoration* ConvertMemberDecoration(uint32_t struct_type_id,
+                                           uint32_t member_index,
+                                           const Decoration& decoration) {
+    return impl_.ConvertMemberDecoration(struct_type_id, member_index,
+                                         decoration);
+  }
+  const spvtools::opt::Instruction* GetMemoryObjectDeclarationForHandle(
+      uint32_t id,
+      bool follow_image) {
+    return impl_.GetMemoryObjectDeclarationForHandle(id, follow_image);
+  }
+  const std::vector<EntryPointInfo>& GetEntryPointInfo(uint32_t entry_point) {
+    return impl_.GetEntryPointInfo(entry_point);
+  }
+  Usage GetHandleUsage(uint32_t id) const { return impl_.GetHandleUsage(id); }
+  bool RegisterHandleUsage() { return impl_.RegisterHandleUsage(); }
+  bool EmitModuleScopeVariables() { return impl_.EmitModuleScopeVariables(); }
+  const spvtools::opt::Instruction* GetInstructionForTest(uint32_t id) const {
+    return impl_.GetInstructionForTest(id);
+  }
+  bool RegisterTypes() { return impl_.RegisterTypes(); }
+  const ParserImpl::BuiltInPositionInfo& GetBuiltInPositionInfo() {
+    return impl_.GetBuiltInPositionInfo();
+  }
+  Source GetSourceForResultIdForTest(uint32_t id) const {
+    return impl_.GetSourceForResultIdForTest(id);
+  }
+  void SetHLSLStylePipelineIO() { impl_.SetHLSLStylePipelineIO(); }
+  bool UseHLSLStylePipelineIO() const { return impl_.UseHLSLStylePipelineIO(); }
+
+ private:
+  ParserImpl impl_;
+};
+
+}  // namespace test
 
 /// SPIR-V Parser test class
 template <typename T>
@@ -37,23 +124,14 @@
   /// Retrieves the parser from the helper
   /// @param input the SPIR-V binary to parse
   /// @returns a parser for the given binary
-  std::unique_ptr<ParserImpl> parser(const std::vector<uint32_t>& input) {
-    auto parser = std::make_unique<ParserImpl>(input);
+  std::unique_ptr<test::ParserImplWrapperForTest> parser(
+      const std::vector<uint32_t>& input) {
+    auto parser = std::make_unique<test::ParserImplWrapperForTest>(input);
     // Don't run the Resolver when building the program.
     // We're not interested in type information with these tests.
     parser->builder().SetResolveOnBuild(false);
     return parser;
   }
-
-  /// Gets the internal representation of the function with the given ID.
-  /// Assumes ParserImpl::BuildInternalRepresentation has been run and
-  /// succeeded.
-  /// @param parser the parser
-  /// @param id the SPIR-V ID of the function
-  /// @returns the internal representation of the function
-  spvtools::opt::Function* spirv_function(ParserImpl* parser, uint32_t id) {
-    return parser->ir_context()->GetFunction(id);
-  }
 };
 
 // Use this form when you don't need to template any further.
diff --git a/src/reader/spirv/spirv_tools_helpers_test.cc b/src/reader/spirv/spirv_tools_helpers_test.cc
index a74f2df..0c97d0f 100644
--- a/src/reader/spirv/spirv_tools_helpers_test.cc
+++ b/src/reader/spirv/spirv_tools_helpers_test.cc
@@ -74,7 +74,8 @@
   });
 
   std::string result;
-  const auto success = tools.Disassemble(spirv_module, &result);
+  const auto success = tools.Disassemble(
+      spirv_module, &result, 0 /* no friendly names, so we get raw IDs */);
   EXPECT_TRUE(success) << errors.str();
 
   return result;