Demangler: Change signature of primary Demangle() function

Have this take a SymbolTable instead of a Program.
Program will be split into Program (immutable) and ProgramBuilder (mutable). We'll need Demangler to support both.

Bug: tint:390
Change-Id: I6447dd9674919d4867ed8ba126880cdfd9bf7128
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/38550
Reviewed-by: dan sinclair <dsinclair@chromium.org>
diff --git a/fuzzers/tint_ast_clone_fuzzer.cc b/fuzzers/tint_ast_clone_fuzzer.cc
index 7b5f951..bbb3f60 100644
--- a/fuzzers/tint_ast_clone_fuzzer.cc
+++ b/fuzzers/tint_ast_clone_fuzzer.cc
@@ -60,7 +60,7 @@
 
   // Expect the demangled AST printed with to_str() to match
   tint::Demangler d;
-  ASSERT_EQ(d.Demangle(src, src.to_str()), d.Demangle(dst, dst.to_str()));
+  ASSERT_EQ(d.Demangle(src), d.Demangle(dst));
 
   // Check that none of the AST nodes or type pointers in dst are found in src
   std::unordered_set<tint::ast::Node*> src_nodes;
diff --git a/samples/main.cc b/samples/main.cc
index b429369..9035b09 100644
--- a/samples/main.cc
+++ b/samples/main.cc
@@ -511,7 +511,7 @@
   if (options.dump_ast) {
     auto ast_str = program.to_str();
     if (options.demangle) {
-      ast_str = tint::Demangler().Demangle(program, ast_str);
+      ast_str = tint::Demangler().Demangle(program.Symbols(), ast_str);
     }
     std::cout << std::endl << ast_str << std::endl;
   }
@@ -558,15 +558,13 @@
 
 #if TINT_BUILD_SPV_WRITER
   if (options.format == Format::kSpirv || options.format == Format::kSpvAsm) {
-    writer =
-        std::make_unique<tint::writer::spirv::Generator>(&program);
+    writer = std::make_unique<tint::writer::spirv::Generator>(&program);
   }
 #endif  // TINT_BUILD_SPV_WRITER
 
 #if TINT_BUILD_WGSL_WRITER
   if (options.format == Format::kWgsl) {
-    writer =
-        std::make_unique<tint::writer::wgsl::Generator>(&program);
+    writer = std::make_unique<tint::writer::wgsl::Generator>(&program);
   }
 #endif  // TINT_BUILD_WGSL_WRITER
 
@@ -578,8 +576,7 @@
 
 #if TINT_BUILD_HLSL_WRITER
   if (options.format == Format::kHlsl) {
-    writer =
-        std::make_unique<tint::writer::hlsl::Generator>(&program);
+    writer = std::make_unique<tint::writer::hlsl::Generator>(&program);
   }
 #endif  // TINT_BUILD_HLSL_WRITER
 
@@ -644,7 +641,7 @@
     auto* w = static_cast<tint::writer::Text*>(writer.get());
     auto output = w->result();
     if (options.demangle) {
-      output = tint::Demangler().Demangle(program, output);
+      output = tint::Demangler().Demangle(program.Symbols(), output);
     }
     if (!WriteFile(options.output_file, "w", output)) {
       return 1;
diff --git a/src/ast/module_clone_test.cc b/src/ast/module_clone_test.cc
index f76bf0d..995b1e5 100644
--- a/src/ast/module_clone_test.cc
+++ b/src/ast/module_clone_test.cc
@@ -118,8 +118,8 @@
 
   // Expect the AST printed with to_str() to match
   Demangler demanger;
-  EXPECT_EQ(demanger.Demangle(src, src.to_str()),
-            demanger.Demangle(dst, dst.to_str()));
+  EXPECT_EQ(demanger.Demangle(src.Symbols(), src.to_str()),
+            demanger.Demangle(dst.Symbols(), dst.to_str()));
 
   // Check that none of the AST nodes or type pointers in dst are found in src
   std::unordered_set<ast::Node*> src_nodes;
diff --git a/src/ast/test_helper.h b/src/ast/test_helper.h
index ab6d468..9f39b02 100644
--- a/src/ast/test_helper.h
+++ b/src/ast/test_helper.h
@@ -35,7 +35,7 @@
   /// @param s the string to demangle
   /// @returns the demangled string
   std::string demangle(const std::string& s) {
-    return demanger.Demangle(*mod, s);
+    return demanger.Demangle(mod->Symbols(), s);
   }
 
   /// A demangler
diff --git a/src/demangler.cc b/src/demangler.cc
index 252af1b..aca97a0 100644
--- a/src/demangler.cc
+++ b/src/demangler.cc
@@ -14,6 +14,9 @@
 
 #include "src/demangler.h"
 
+#include "src/ast/module.h"
+#include "src/program.h"
+
 namespace tint {
 namespace {
 
@@ -26,7 +29,7 @@
 
 Demangler::~Demangler() = default;
 
-std::string Demangler::Demangle(const Program& program,
+std::string Demangler::Demangle(const SymbolTable& symbols,
                                 const std::string& str) const {
   auto ret = str;
 
@@ -46,7 +49,7 @@
     auto id = ret.substr(start_idx, len);
 
     Symbol sym(std::stoi(id));
-    auto name = program.Symbols().NameFor(sym);
+    auto name = symbols.NameFor(sym);
     ret.replace(idx, end_idx - idx, name);
 
     pos = idx + name.length();
@@ -55,4 +58,8 @@
   return ret;
 }
 
+std::string Demangler::Demangle(const Program& program) const {
+  return Demangle(program.Symbols(), program.AST().to_str());
+}
+
 }  // namespace tint
diff --git a/src/demangler.h b/src/demangler.h
index 9496d6c..f5ecb03 100644
--- a/src/demangler.h
+++ b/src/demangler.h
@@ -17,10 +17,11 @@
 
 #include <string>
 
-#include "src/program.h"
-
 namespace tint {
 
+class Program;
+class SymbolTable;
+
 /// Helper to demangle strings and replace symbols with original names
 class Demangler {
  public:
@@ -30,10 +31,17 @@
   ~Demangler();
 
   /// Transforms given string and replaces any symbols with original names
-  /// @param program the program where the symbols are registered
+  /// @param symbols the symbol table
   /// @param str the string to replace
   /// @returns the string with any symbol replacements performed.
-  std::string Demangle(const Program& program, const std::string& str) const;
+  std::string Demangle(const SymbolTable& symbols,
+                       const std::string& str) const;
+
+  /// Returns the string returned by the `program.AST().to_str()` of the
+  /// program with all symbols replaced with their original names.
+  /// @param program the program where the symbols are registered
+  /// @returns the string with any symbol replacements performed.
+  std::string Demangle(const Program& program) const;
 };
 
 }  // namespace tint
diff --git a/src/demangler_test.cc b/src/demangler_test.cc
index 3c41285..b4e00d0 100644
--- a/src/demangler_test.cc
+++ b/src/demangler_test.cc
@@ -13,9 +13,9 @@
 // limitations under the License.
 
 #include "src/demangler.h"
+#include "src/symbol_table.h"
 
 #include "gtest/gtest.h"
-#include "src/program.h"
 
 namespace tint {
 namespace {
@@ -23,30 +23,30 @@
 using DemanglerTest = testing::Test;
 
 TEST_F(DemanglerTest, NoSymbols) {
-  Program m;
-  m.Symbols().Register("sym1");
+  SymbolTable t;
+  t.Register("sym1");
 
   Demangler d;
-  EXPECT_EQ("test str", d.Demangle(m, "test str"));
+  EXPECT_EQ("test str", d.Demangle(t, "test str"));
 }
 
 TEST_F(DemanglerTest, Symbol) {
-  Program m;
-  m.Symbols().Register("sym1");
+  SymbolTable t;
+  t.Register("sym1");
 
   Demangler d;
-  EXPECT_EQ("test sym1 str", d.Demangle(m, "test tint_symbol_1 str"));
+  EXPECT_EQ("test sym1 str", d.Demangle(t, "test tint_symbol_1 str"));
 }
 
 TEST_F(DemanglerTest, MultipleSymbols) {
-  Program m;
-  m.Symbols().Register("sym1");
-  m.Symbols().Register("sym2");
+  SymbolTable t;
+  t.Register("sym1");
+  t.Register("sym2");
 
   Demangler d;
   EXPECT_EQ(
       "test sym1 sym2 sym1 str",
-      d.Demangle(m, "test tint_symbol_1 tint_symbol_2 tint_symbol_1 str"));
+      d.Demangle(t, "test tint_symbol_1 tint_symbol_2 tint_symbol_1 str"));
 }
 
 }  // namespace
diff --git a/src/reader/spirv/function_call_test.cc b/src/reader/spirv/function_call_test.cc
index d830d7c..c88e7cc 100644
--- a/src/reader/spirv/function_call_test.cc
+++ b/src/reader/spirv/function_call_test.cc
@@ -216,8 +216,7 @@
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModule()) << p->error();
   EXPECT_TRUE(p->error().empty());
-  const auto program_ast_str =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto program_ast_str = Demangler().Demangle(p->get_program());
   EXPECT_THAT(program_ast_str, HasSubstr(R"(Module{
   Function x_50 -> __u32
   (
diff --git a/src/reader/spirv/function_decl_test.cc b/src/reader/spirv/function_decl_test.cc
index 6d83356..614d7ae 100644
--- a/src/reader/spirv/function_decl_test.cc
+++ b/src/reader/spirv/function_decl_test.cc
@@ -59,7 +59,7 @@
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
   FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
   EXPECT_TRUE(fe.Emit());
-  auto got = Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  auto got = Demangler().Demangle(p->get_program());
   std::string expect = R"(Module{
   Function x_100 -> __void
   ()
@@ -83,7 +83,7 @@
   FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
   EXPECT_TRUE(fe.Emit());
 
-  auto got = Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  auto got = Demangler().Demangle(p->get_program());
   std::string expect = R"(Module{
   Function x_100 -> __f32
   ()
@@ -115,7 +115,7 @@
   FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
   EXPECT_TRUE(fe.Emit());
 
-  auto got = Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  auto got = Demangler().Demangle(p->get_program());
   std::string expect = R"(Module{
   Function x_100 -> __void
   (
@@ -159,7 +159,7 @@
   FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
   EXPECT_TRUE(fe.Emit());
 
-  auto got = Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  auto got = Demangler().Demangle(p->get_program());
   std::string expect = R"(Module{
   Function x_100 -> __void
   (
diff --git a/src/reader/spirv/function_memory_test.cc b/src/reader/spirv/function_memory_test.cc
index bc9e7f9..94d460a 100644
--- a/src/reader/spirv/function_memory_test.cc
+++ b/src/reader/spirv/function_memory_test.cc
@@ -813,8 +813,7 @@
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions())
       << assembly << p->error();
-  const auto module_str =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto module_str = Demangler().Demangle(p->get_program());
   EXPECT_THAT(module_str, HasSubstr(R"(
   RTArr -> __array__u32_stride_4
   S Struct{
diff --git a/src/reader/spirv/function_misc_test.cc b/src/reader/spirv/function_misc_test.cc
index 978b1b6..6a22ebd 100644
--- a/src/reader/spirv/function_misc_test.cc
+++ b/src/reader/spirv/function_misc_test.cc
@@ -329,7 +329,7 @@
     ASSERT_NE(result, nullptr);
     std::ostringstream ss;
     result->to_str(ss, 0);
-    auto str = Demangler().Demangle(p->get_program(), ss.str());
+    auto str = Demangler().Demangle(p->get_program().Symbols(), ss.str());
     EXPECT_THAT(str, Eq(GetParam().expected_expr));
   } else {
     EXPECT_EQ(result, nullptr);
diff --git a/src/reader/spirv/parser_impl_convert_type_test.cc b/src/reader/spirv/parser_impl_convert_type_test.cc
index f76b004..766021f 100644
--- a/src/reader/spirv/parser_impl_convert_type_test.cc
+++ b/src/reader/spirv/parser_impl_convert_type_test.cc
@@ -566,7 +566,8 @@
   EXPECT_TRUE(type->Is<type::Struct>());
   std::stringstream ss;
   type->As<type::Struct>()->impl()->to_str(ss, 0);
-  EXPECT_THAT(Demangler().Demangle(p->get_program(), ss.str()), Eq(R"(Struct{
+  EXPECT_THAT(Demangler().Demangle(p->get_program().Symbols(), ss.str()),
+              Eq(R"(Struct{
   StructMember{field0: __u32}
   StructMember{field1: __f32}
 }
@@ -587,7 +588,8 @@
   EXPECT_TRUE(type->Is<type::Struct>());
   std::stringstream ss;
   type->As<type::Struct>()->impl()->to_str(ss, 0);
-  EXPECT_THAT(Demangler().Demangle(p->get_program(), ss.str()), Eq(R"(Struct{
+  EXPECT_THAT(Demangler().Demangle(p->get_program().Symbols(), ss.str()),
+              Eq(R"(Struct{
   [[block]]
   StructMember{field0: __u32}
 }
@@ -612,7 +614,8 @@
   EXPECT_TRUE(type->Is<type::Struct>());
   std::stringstream ss;
   type->As<type::Struct>()->impl()->to_str(ss, 0);
-  EXPECT_THAT(Demangler().Demangle(p->get_program(), ss.str()), Eq(R"(Struct{
+  EXPECT_THAT(Demangler().Demangle(p->get_program().Symbols(), ss.str()),
+              Eq(R"(Struct{
   StructMember{[[ offset 0 ]] field0: __f32}
   StructMember{[[ offset 8 ]] field1: __vec_2__f32}
   StructMember{[[ offset 16 ]] field2: __mat_2_2__f32}
diff --git a/src/reader/spirv/parser_impl_function_decl_test.cc b/src/reader/spirv/parser_impl_function_decl_test.cc
index 897b740..fce07a9 100644
--- a/src/reader/spirv/parser_impl_function_decl_test.cc
+++ b/src/reader/spirv/parser_impl_function_decl_test.cc
@@ -199,8 +199,7 @@
   )"));
   EXPECT_TRUE(p->BuildAndParseInternalModule());
   EXPECT_TRUE(p->error().empty());
-  const auto program_ast =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto program_ast = Demangler().Demangle(p->get_program());
   EXPECT_THAT(program_ast, HasSubstr(R"(
   Function leaf -> __u32
   ()
@@ -267,8 +266,7 @@
   )"));
   EXPECT_TRUE(p->BuildAndParseInternalModule());
   EXPECT_TRUE(p->error().empty());
-  const auto program_ast =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto program_ast = Demangler().Demangle(p->get_program());
   EXPECT_THAT(program_ast, HasSubstr(R"(
   Function ret_float -> __f32
   ()
@@ -297,8 +295,7 @@
   )"));
   EXPECT_TRUE(p->BuildAndParseInternalModule());
   EXPECT_TRUE(p->error().empty());
-  const auto program_ast =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto program_ast = Demangler().Demangle(p->get_program());
   EXPECT_THAT(program_ast, HasSubstr(R"(
   Function mixed_params -> __void
   (
@@ -337,8 +334,7 @@
   )"));
   EXPECT_TRUE(p->BuildAndParseInternalModule());
   EXPECT_TRUE(p->error().empty());
-  const auto program_ast =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto program_ast = Demangler().Demangle(p->get_program());
   EXPECT_THAT(program_ast, HasSubstr(R"(
   Function mixed_params -> __void
   (
diff --git a/src/reader/spirv/parser_impl_handle_test.cc b/src/reader/spirv/parser_impl_handle_test.cc
index 3bdd6e1..d1d5f6c 100644
--- a/src/reader/spirv/parser_impl_handle_test.cc
+++ b/src/reader/spirv/parser_impl_handle_test.cc
@@ -1129,8 +1129,7 @@
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModule()) << p->error() << assembly;
   EXPECT_TRUE(p->error().empty()) << p->error();
-  const auto program =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto program = Demangler().Demangle(p->get_program());
   EXPECT_THAT(program, HasSubstr(GetParam().var_decl)) << program;
 }
 
@@ -1306,8 +1305,7 @@
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModule()) << p->error() << assembly;
   EXPECT_TRUE(p->error().empty()) << p->error();
-  const auto program =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto program = Demangler().Demangle(p->get_program());
   EXPECT_THAT(program, HasSubstr(GetParam().var_decl))
       << "DECLARATIONS ARE BAD " << program;
   EXPECT_THAT(program, HasSubstr(GetParam().texture_builtin))
@@ -2556,8 +2554,7 @@
   auto p = parser(test::Assemble(assembly));
   ASSERT_TRUE(p->BuildAndParseInternalModule()) << p->error() << assembly;
   EXPECT_TRUE(p->error().empty()) << p->error();
-  const auto program =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto program = Demangler().Demangle(p->get_program());
   EXPECT_THAT(program, HasSubstr(GetParam().var_decl))
       << "DECLARATIONS ARE BAD " << program;
   EXPECT_THAT(program, HasSubstr(GetParam().texture_builtin))
@@ -3712,7 +3709,7 @@
       for (auto* expr : result) {
         ASSERT_NE(expr, nullptr);
         result_strings.push_back(
-            Demangler().Demangle(p->get_program(), expr->str()));
+            Demangler().Demangle(p->get_program().Symbols(), expr->str()));
       }
       EXPECT_THAT(result_strings,
                   ::testing::ContainerEq(GetParam().expected_expressions));
diff --git a/src/reader/spirv/parser_impl_module_var_test.cc b/src/reader/spirv/parser_impl_module_var_test.cc
index fd35169..085b3db 100644
--- a/src/reader/spirv/parser_impl_module_var_test.cc
+++ b/src/reader/spirv/parser_impl_module_var_test.cc
@@ -143,8 +143,7 @@
 
   EXPECT_TRUE(p->BuildAndParseInternalModule());
   EXPECT_TRUE(p->error().empty());
-  const auto module_str =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto module_str = Demangler().Demangle(p->get_program());
   EXPECT_THAT(module_str, HasSubstr(R"(
   Variable{
     x_52
@@ -163,8 +162,7 @@
 
   EXPECT_TRUE(p->BuildAndParseInternalModule());
   EXPECT_TRUE(p->error().empty());
-  const auto module_str =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto module_str = Demangler().Demangle(p->get_program());
   EXPECT_THAT(module_str, HasSubstr(R"(
   Variable{
     the_counter
@@ -183,8 +181,7 @@
 
   EXPECT_TRUE(p->BuildAndParseInternalModule());
   EXPECT_TRUE(p->error().empty());
-  const auto module_str =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto module_str = Demangler().Demangle(p->get_program());
   EXPECT_THAT(module_str, HasSubstr(R"(
   Variable{
     my_own_private_idaho
@@ -203,8 +200,7 @@
 
   EXPECT_TRUE(p->BuildAndParseInternalModule());
   EXPECT_TRUE(p->error().empty());
-  const auto module_str =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto module_str = Demangler().Demangle(p->get_program());
   EXPECT_THAT(module_str, HasSubstr(R"(
   Variable{
     Decorations{
@@ -254,8 +250,7 @@
   EXPECT_EQ(position_info.pointer_type_id, 11u);
   EXPECT_EQ(position_info.storage_class, SpvStorageClassOutput);
   EXPECT_EQ(position_info.per_vertex_var_id, 1u);
-  const auto module_str =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto module_str = Demangler().Demangle(p->get_program());
   EXPECT_THAT(module_str, HasSubstr(R"(
   Variable{
     Decorations{
@@ -335,8 +330,7 @@
   auto p = parser(test::Assemble(assembly));
   EXPECT_TRUE(p->BuildAndParseInternalModule());
   EXPECT_TRUE(p->error().empty());
-  const auto module_str =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto module_str = Demangler().Demangle(p->get_program());
   EXPECT_THAT(module_str, HasSubstr(R"(
     Assignment{
       Identifier[not set]{gl_Position}
@@ -389,8 +383,7 @@
   auto p = parser(test::Assemble(assembly));
   EXPECT_TRUE(p->BuildAndParseInternalModule());
   EXPECT_TRUE(p->error().empty());
-  const auto module_str =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto module_str = Demangler().Demangle(p->get_program());
   EXPECT_THAT(module_str, HasSubstr(R"(
     Assignment{
       Identifier[not set]{gl_Position}
@@ -421,8 +414,7 @@
   auto p = parser(test::Assemble(assembly));
   EXPECT_TRUE(p->BuildAndParseInternalModule());
   EXPECT_TRUE(p->error().empty());
-  const auto module_str =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto module_str = Demangler().Demangle(p->get_program());
   EXPECT_THAT(module_str, HasSubstr(R"(
     Assignment{
       MemberAccessor[not set]{
@@ -453,8 +445,7 @@
   auto p = parser(test::Assemble(assembly));
   EXPECT_TRUE(p->BuildAndParseInternalModule());
   EXPECT_TRUE(p->error().empty());
-  const auto module_str =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto module_str = Demangler().Demangle(p->get_program());
   EXPECT_THAT(module_str, HasSubstr(R"(
   {
     Assignment{
@@ -484,8 +475,7 @@
   auto p = parser(test::Assemble(assembly));
   EXPECT_TRUE(p->BuildAndParseInternalModule());
   EXPECT_TRUE(p->error().empty());
-  const auto module_str =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto module_str = Demangler().Demangle(p->get_program());
   EXPECT_EQ(module_str, R"(Module{
   Variable{
     Decorations{
@@ -541,8 +531,7 @@
   auto p = parser(test::Assemble(assembly));
   EXPECT_TRUE(p->BuildAndParseInternalModule());
   EXPECT_TRUE(p->error().empty());
-  const auto module_str =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto module_str = Demangler().Demangle(p->get_program());
   EXPECT_EQ(module_str, R"(Module{
   Variable{
     x_900
@@ -609,8 +598,7 @@
   auto p = parser(test::Assemble(assembly));
   EXPECT_TRUE(p->BuildAndParseInternalModule()) << p->error();
   EXPECT_TRUE(p->error().empty());
-  const auto module_str =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto module_str = Demangler().Demangle(p->get_program());
   EXPECT_EQ(module_str, R"(Module{
   Variable{
     Decorations{
@@ -661,8 +649,7 @@
   auto p = parser(test::Assemble(assembly));
   EXPECT_TRUE(p->BuildAndParseInternalModule());
   EXPECT_TRUE(p->error().empty());
-  const auto module_str =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto module_str = Demangler().Demangle(p->get_program());
   EXPECT_EQ(module_str, R"(Module{
   Function x_500 -> __void
   ()
@@ -706,8 +693,7 @@
   auto p = parser(test::Assemble(assembly));
   EXPECT_TRUE(p->BuildAndParseInternalModule());
   EXPECT_TRUE(p->error().empty());
-  const auto module_str =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto module_str = Demangler().Demangle(p->get_program());
   EXPECT_EQ(module_str, R"(Module{
   Variable{
     x_900
@@ -743,8 +729,7 @@
   auto p = parser(test::Assemble(assembly));
   EXPECT_TRUE(p->BuildAndParseInternalModule()) << p->error();
   EXPECT_TRUE(p->error().empty());
-  const auto module_str =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto module_str = Demangler().Demangle(p->get_program());
   EXPECT_EQ(module_str, R"(Module{
   Function x_500 -> __void
   ()
@@ -771,8 +756,7 @@
   auto p = parser(test::Assemble(assembly));
   EXPECT_TRUE(p->BuildAndParseInternalModule()) << p->error();
   EXPECT_TRUE(p->error().empty()) << p->error();
-  const auto module_str =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto module_str = Demangler().Demangle(p->get_program());
   EXPECT_EQ(module_str, R"(Module{
   Function x_500 -> __void
   ()
@@ -876,8 +860,7 @@
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
   EXPECT_TRUE(p->error().empty());
-  const auto module_str =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto module_str = Demangler().Demangle(p->get_program());
   EXPECT_THAT(module_str, HasSubstr(R"(Variable{
     x_1
     private
@@ -934,8 +917,7 @@
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
   EXPECT_TRUE(p->error().empty());
-  const auto module_str =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto module_str = Demangler().Demangle(p->get_program());
   EXPECT_THAT(module_str, HasSubstr(R"(Variable{
     x_1
     private
@@ -984,8 +966,7 @@
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
   EXPECT_TRUE(p->error().empty());
-  const auto module_str =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto module_str = Demangler().Demangle(p->get_program());
   EXPECT_THAT(module_str, HasSubstr(R"(Variable{
     x_1
     private
@@ -1029,8 +1010,7 @@
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
   EXPECT_TRUE(p->error().empty());
-  const auto module_str =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto module_str = Demangler().Demangle(p->get_program());
   EXPECT_THAT(module_str, HasSubstr(R"(Variable{
     x_200
     private
@@ -1053,8 +1033,7 @@
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
   EXPECT_TRUE(p->error().empty());
-  const auto module_str =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto module_str = Demangler().Demangle(p->get_program());
   EXPECT_THAT(module_str, HasSubstr(R"(Variable{
     x_200
     private
@@ -1077,8 +1056,7 @@
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
   EXPECT_TRUE(p->error().empty());
-  const auto module_str =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto module_str = Demangler().Demangle(p->get_program());
   EXPECT_THAT(module_str, HasSubstr(R"(Variable{
     x_200
     private
@@ -1101,8 +1079,7 @@
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
   EXPECT_TRUE(p->error().empty());
-  const auto module_str =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto module_str = Demangler().Demangle(p->get_program());
   EXPECT_THAT(module_str, HasSubstr(R"(Variable{
     x_200
     private
@@ -1125,8 +1102,7 @@
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
   EXPECT_TRUE(p->error().empty());
-  const auto module_str =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto module_str = Demangler().Demangle(p->get_program());
   EXPECT_THAT(module_str, HasSubstr(R"(Variable{
     x_200
     private
@@ -1149,8 +1125,7 @@
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
   EXPECT_TRUE(p->error().empty());
-  const auto module_str =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto module_str = Demangler().Demangle(p->get_program());
   EXPECT_THAT(module_str, HasSubstr(R"(Variable{
     x_200
     private
@@ -1173,8 +1148,7 @@
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
   EXPECT_TRUE(p->error().empty());
-  const auto module_str =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto module_str = Demangler().Demangle(p->get_program());
   EXPECT_THAT(module_str, HasSubstr(R"(Variable{
     x_200
     private
@@ -1197,8 +1171,7 @@
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
   EXPECT_TRUE(p->error().empty());
-  const auto module_str =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto module_str = Demangler().Demangle(p->get_program());
   EXPECT_THAT(module_str, HasSubstr(R"(Variable{
     x_200
     private
@@ -1221,8 +1194,7 @@
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
   EXPECT_TRUE(p->error().empty());
-  const auto module_str =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto module_str = Demangler().Demangle(p->get_program());
   EXPECT_THAT(module_str, HasSubstr(R"(Variable{
     x_200
     private
@@ -1251,8 +1223,7 @@
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
   EXPECT_TRUE(p->error().empty());
-  const auto module_str =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto module_str = Demangler().Demangle(p->get_program());
   EXPECT_THAT(module_str, HasSubstr(R"(Variable{
     x_200
     private
@@ -1288,8 +1259,7 @@
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
   EXPECT_TRUE(p->error().empty());
-  const auto module_str =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto module_str = Demangler().Demangle(p->get_program());
   EXPECT_THAT(module_str, HasSubstr(R"(Variable{
     x_200
     private
@@ -1325,8 +1295,7 @@
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
   EXPECT_TRUE(p->error().empty());
-  const auto module_str =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto module_str = Demangler().Demangle(p->get_program());
   EXPECT_THAT(module_str, HasSubstr(R"(Variable{
     x_200
     private
@@ -1363,8 +1332,7 @@
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
   EXPECT_TRUE(p->error().empty());
-  const auto module_str =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto module_str = Demangler().Demangle(p->get_program());
   EXPECT_THAT(module_str, HasSubstr(R"(Variable{
     x_200
     private
@@ -1387,8 +1355,7 @@
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
   EXPECT_TRUE(p->error().empty());
-  const auto module_str =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto module_str = Demangler().Demangle(p->get_program());
   EXPECT_THAT(module_str, HasSubstr(R"(Variable{
     x_200
     private
@@ -1411,8 +1378,7 @@
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
   EXPECT_TRUE(p->error().empty());
-  const auto module_str =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto module_str = Demangler().Demangle(p->get_program());
   EXPECT_THAT(module_str, HasSubstr(R"(Variable{
     x_200
     private
@@ -1437,8 +1403,7 @@
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
   EXPECT_TRUE(p->error().empty());
-  const auto module_str =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto module_str = Demangler().Demangle(p->get_program());
   EXPECT_THAT(module_str, HasSubstr(R"(Variable{
     x_200
     private
@@ -1467,8 +1432,7 @@
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
   EXPECT_TRUE(p->error().empty());
-  const auto module_str =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto module_str = Demangler().Demangle(p->get_program());
   EXPECT_THAT(module_str, HasSubstr(R"(Variable{
     x_200
     private
@@ -1497,8 +1461,7 @@
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
   EXPECT_TRUE(p->error().empty());
-  const auto module_str =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto module_str = Demangler().Demangle(p->get_program());
   EXPECT_THAT(module_str, HasSubstr(R"(Variable{
     x_200
     private
@@ -1529,8 +1492,7 @@
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
   EXPECT_TRUE(p->error().empty());
-  const auto module_str =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto module_str = Demangler().Demangle(p->get_program());
   EXPECT_THAT(module_str, HasSubstr(R"(
   Variable{
     Decorations{
@@ -1582,8 +1544,7 @@
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
   EXPECT_TRUE(p->error().empty());
-  const auto module_str =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto module_str = Demangler().Demangle(p->get_program());
   EXPECT_THAT(module_str, HasSubstr(R"(
   Variable{
     Decorations{
@@ -1637,8 +1598,7 @@
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
   EXPECT_TRUE(p->error().empty());
-  const auto module_str =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto module_str = Demangler().Demangle(p->get_program());
   EXPECT_THAT(module_str, HasSubstr(R"(
   Variable{
     Decorations{
@@ -1692,8 +1652,7 @@
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
   EXPECT_TRUE(p->error().empty());
-  const auto module_str =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto module_str = Demangler().Demangle(p->get_program());
   EXPECT_THAT(module_str, HasSubstr(R"(
   S Struct{
     [[block]]
@@ -1724,8 +1683,7 @@
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
   EXPECT_TRUE(p->error().empty());
-  const auto module_str =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto module_str = Demangler().Demangle(p->get_program());
   EXPECT_THAT(module_str, HasSubstr(R"(
   S Struct{
     [[block]]
@@ -1754,8 +1712,7 @@
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
   EXPECT_TRUE(p->error().empty());
-  const auto module_str =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto module_str = Demangler().Demangle(p->get_program());
   EXPECT_THAT(module_str, HasSubstr(R"(
   S Struct{
     [[block]]
@@ -1804,8 +1761,7 @@
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
   EXPECT_TRUE(p->error().empty());
-  const auto module_str =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto module_str = Demangler().Demangle(p->get_program());
   EXPECT_THAT(module_str, HasSubstr(R"(
   S Struct{
     [[block]]
@@ -1834,8 +1790,7 @@
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
   EXPECT_TRUE(p->error().empty());
-  const auto module_str =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto module_str = Demangler().Demangle(p->get_program());
   EXPECT_THAT(module_str, HasSubstr(R"(
   S Struct{
     [[block]]
@@ -1867,8 +1822,7 @@
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
   EXPECT_TRUE(p->error().empty());
-  const auto module_str =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto module_str = Demangler().Demangle(p->get_program());
   EXPECT_THAT(module_str, HasSubstr(R"(
   S Struct{
     [[block]]
@@ -1892,8 +1846,7 @@
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
   EXPECT_TRUE(p->error().empty());
-  const auto module_str =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto module_str = Demangler().Demangle(p->get_program());
   EXPECT_THAT(module_str, HasSubstr(R"(
   VariableConst{
     Decorations{
@@ -1918,8 +1871,7 @@
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
   EXPECT_TRUE(p->error().empty());
-  const auto module_str =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto module_str = Demangler().Demangle(p->get_program());
   EXPECT_THAT(module_str, HasSubstr(R"(
   VariableConst{
     Decorations{
@@ -1944,8 +1896,7 @@
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
   EXPECT_TRUE(p->error().empty());
-  const auto module_str =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto module_str = Demangler().Demangle(p->get_program());
   EXPECT_THAT(module_str, HasSubstr(R"(
   VariableConst{
     Decorations{
@@ -1970,8 +1921,7 @@
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
   EXPECT_TRUE(p->error().empty());
-  const auto module_str =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto module_str = Demangler().Demangle(p->get_program());
   EXPECT_THAT(module_str, HasSubstr(R"(
   VariableConst{
     Decorations{
@@ -1996,8 +1946,7 @@
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
   EXPECT_TRUE(p->error().empty());
-  const auto module_str =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto module_str = Demangler().Demangle(p->get_program());
   EXPECT_THAT(module_str, HasSubstr(R"(
   VariableConst{
     Decorations{
@@ -2023,8 +1972,7 @@
   )"));
   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
   EXPECT_TRUE(p->error().empty());
-  const auto module_str =
-      Demangler().Demangle(p->get_program(), p->get_program().to_str());
+  const auto module_str = Demangler().Demangle(p->get_program());
   EXPECT_THAT(module_str, HasSubstr(R"(
   VariableConst{
     myconst
diff --git a/src/reader/spirv/parser_impl_named_types_test.cc b/src/reader/spirv/parser_impl_named_types_test.cc
index d1c46f9..04dd8ac 100644
--- a/src/reader/spirv/parser_impl_named_types_test.cc
+++ b/src/reader/spirv/parser_impl_named_types_test.cc
@@ -40,8 +40,7 @@
     %s = OpTypeStruct %uint %uint
   )"));
   EXPECT_TRUE(p->BuildAndParseInternalModule());
-  EXPECT_THAT(Demangler().Demangle(p->get_program(), p->get_program().to_str()),
-              HasSubstr("S Struct"));
+  EXPECT_THAT(Demangler().Demangle(p->get_program()), HasSubstr("S Struct"));
 }
 
 TEST_F(SpvParserTest, NamedTypes_NamedStruct) {
@@ -51,7 +50,7 @@
     %s = OpTypeStruct %uint %uint
   )"));
   EXPECT_TRUE(p->BuildAndParseInternalModule());
-  EXPECT_THAT(Demangler().Demangle(p->get_program(), p->get_program().to_str()),
+  EXPECT_THAT(Demangler().Demangle(p->get_program()),
               HasSubstr("mystruct Struct"));
 }
 
@@ -62,8 +61,7 @@
     %s2 = OpTypeStruct %uint %uint
   )"));
   EXPECT_TRUE(p->BuildAndParseInternalModule()) << p->error();
-  EXPECT_THAT(Demangler().Demangle(p->get_program(), p->get_program().to_str()),
-              HasSubstr(R"(S Struct{
+  EXPECT_THAT(Demangler().Demangle(p->get_program()), HasSubstr(R"(S Struct{
     StructMember{field0: __u32}
     StructMember{field1: __u32}
   }
@@ -84,7 +82,7 @@
     %arr = OpTypeRuntimeArray %uint
   )"));
   EXPECT_TRUE(p->BuildAndParseInternalModule());
-  EXPECT_THAT(Demangler().Demangle(p->get_program(), p->get_program().to_str()),
+  EXPECT_THAT(Demangler().Demangle(p->get_program()),
               HasSubstr("RTArr -> __array__u32_stride_8\n"));
 }
 
@@ -97,7 +95,7 @@
     %arr2 = OpTypeRuntimeArray %uint
   )"));
   EXPECT_TRUE(p->BuildAndParseInternalModule());
-  EXPECT_THAT(Demangler().Demangle(p->get_program(), p->get_program().to_str()),
+  EXPECT_THAT(Demangler().Demangle(p->get_program()),
               HasSubstr("RTArr -> __array__u32_stride_8\n  RTArr_1 -> "
                         "__array__u32_stride_8\n"));
 }
@@ -110,7 +108,7 @@
     %arr = OpTypeRuntimeArray %uint
   )"));
   EXPECT_TRUE(p->BuildAndParseInternalModule());
-  EXPECT_THAT(Demangler().Demangle(p->get_program(), p->get_program().to_str()),
+  EXPECT_THAT(Demangler().Demangle(p->get_program()),
               HasSubstr("myrtarr -> __array__u32_stride_8\n"));
 }
 
@@ -124,7 +122,7 @@
     %arr2 = OpTypeArray %uint %uint_5
   )"));
   EXPECT_TRUE(p->BuildAndParseInternalModule());
-  EXPECT_THAT(Demangler().Demangle(p->get_program(), p->get_program().to_str()),
+  EXPECT_THAT(Demangler().Demangle(p->get_program()),
               HasSubstr("myarr -> __array__u32_5_stride_8"));
 }
 
@@ -138,7 +136,7 @@
     %arr2 = OpTypeArray %uint %uint_5
   )"));
   EXPECT_TRUE(p->BuildAndParseInternalModule());
-  EXPECT_THAT(Demangler().Demangle(p->get_program(), p->get_program().to_str()),
+  EXPECT_THAT(Demangler().Demangle(p->get_program()),
               HasSubstr("Arr -> __array__u32_5_stride_8\n  Arr_1 -> "
                         "__array__u32_5_stride_8"));
 }
diff --git a/src/reader/spirv/parser_impl_test_helper.h b/src/reader/spirv/parser_impl_test_helper.h
index c296e87..86ca5a9 100644
--- a/src/reader/spirv/parser_impl_test_helper.h
+++ b/src/reader/spirv/parser_impl_test_helper.h
@@ -67,7 +67,7 @@
   for (const auto* stmt : stmts) {
     stmt->to_str(outs, 0);
   }
-  return Demangler().Demangle(program, outs.str());
+  return Demangler().Demangle(program.Symbols(), outs.str());
 }
 
 }  // namespace spirv
diff --git a/src/type/test_helper.h b/src/type/test_helper.h
index 3a96f78..ac0a328 100644
--- a/src/type/test_helper.h
+++ b/src/type/test_helper.h
@@ -35,7 +35,7 @@
   /// @param s the string to demangle
   /// @returns the demangled string
   std::string demangle(const std::string& s) {
-    return demanger.Demangle(*mod, s);
+    return demanger.Demangle(mod->Symbols(), s);
   }
 
   /// A demangler