diff --git a/BUILD.gn b/BUILD.gn index 61f5862795..d59faf4da7 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -390,6 +390,8 @@ source_set("libtint_core_src") { "src/ast/workgroup_decoration.h", "src/castable.cc", "src/castable.h", + "src/demangler.cc", + "src/demangler.h", "src/diagnostic/diagnostic.cc", "src/diagnostic/diagnostic.h", "src/diagnostic/formatter.cc", @@ -817,6 +819,7 @@ source_set("tint_unittests_core_src") { "src/ast/variable_test.cc", "src/ast/workgroup_decoration_test.cc", "src/castable_test.cc", + "src/demangler_test.cc", "src/diagnostic/formatter_test.cc", "src/diagnostic/printer_test.cc", "src/inspector/inspector_test.cc", diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a80cd1a9a1..9a063afd22 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -211,6 +211,8 @@ set(TINT_LIB_SRCS ast/workgroup_decoration.h castable.cc castable.h + demangler.cc + demangler.h; diagnostic/diagnostic.cc diagnostic/diagnostic.h diagnostic/formatter.cc @@ -454,6 +456,7 @@ if(${TINT_BUILD_TESTS}) ast/variable_test.cc ast/workgroup_decoration_test.cc castable_test.cc + demangler_test.cc diagnostic/formatter_test.cc diagnostic/printer_test.cc inspector/inspector_test.cc diff --git a/src/ast/function_test.cc b/src/ast/function_test.cc index e341fc83c7..89bc80a386 100644 --- a/src/ast/function_test.cc +++ b/src/ast/function_test.cc @@ -35,8 +35,7 @@ TEST_F(FunctionTest, Creation) { type::Void void_type; type::I32 i32; - Module m; - auto func_sym = m.RegisterSymbol("func"); + auto func_sym = mod.RegisterSymbol("func"); VariableList params; params.push_back(create(Source{}, "var", StorageClass::kNone, &i32, @@ -57,8 +56,7 @@ TEST_F(FunctionTest, Creation_WithSource) { type::Void void_type; type::I32 i32; - Module m; - auto func_sym = m.RegisterSymbol("func"); + auto func_sym = mod.RegisterSymbol("func"); VariableList params; params.push_back(create(Source{}, "var", StorageClass::kNone, &i32, @@ -76,8 +74,7 @@ TEST_F(FunctionTest, AddDuplicateReferencedVariables) { type::Void void_type; type::I32 i32; - Module m; - auto func_sym = m.RegisterSymbol("func"); + auto func_sym = mod.RegisterSymbol("func"); Variable v(Source{}, "var", StorageClass::kInput, &i32, false, nullptr, ast::VariableDecorationList{}); @@ -102,8 +99,7 @@ TEST_F(FunctionTest, GetReferenceLocations) { type::Void void_type; type::I32 i32; - Module m; - auto func_sym = m.RegisterSymbol("func"); + auto func_sym = mod.RegisterSymbol("func"); auto* loc1 = create(Source{}, "loc1", StorageClass::kInput, &i32, false, nullptr, @@ -150,8 +146,7 @@ TEST_F(FunctionTest, GetReferenceBuiltins) { type::Void void_type; type::I32 i32; - Module m; - auto func_sym = m.RegisterSymbol("func"); + auto func_sym = mod.RegisterSymbol("func"); auto* loc1 = create(Source{}, "loc1", StorageClass::kInput, &i32, false, nullptr, @@ -197,9 +192,8 @@ TEST_F(FunctionTest, GetReferenceBuiltins) { TEST_F(FunctionTest, AddDuplicateEntryPoints) { type::Void void_type; - Module m; - auto func_sym = m.RegisterSymbol("func"); - auto main_sym = m.RegisterSymbol("main"); + auto func_sym = mod.RegisterSymbol("func"); + auto main_sym = mod.RegisterSymbol("main"); Function f(Source{}, func_sym, "func", VariableList{}, &void_type, create(), FunctionDecorationList{}); @@ -217,8 +211,7 @@ TEST_F(FunctionTest, IsValid) { type::Void void_type; type::I32 i32; - Module m; - auto func_sym = m.RegisterSymbol("func"); + auto func_sym = mod.RegisterSymbol("func"); VariableList params; params.push_back(create(Source{}, "var", StorageClass::kNone, &i32, @@ -237,8 +230,7 @@ TEST_F(FunctionTest, IsValid_InvalidName) { type::Void void_type; type::I32 i32; - Module m; - auto func_sym = m.RegisterSymbol(""); + auto func_sym = mod.RegisterSymbol(""); VariableList params; params.push_back(create(Source{}, "var", StorageClass::kNone, &i32, @@ -256,8 +248,7 @@ TEST_F(FunctionTest, IsValid_InvalidName) { TEST_F(FunctionTest, IsValid_MissingReturnType) { type::I32 i32; - Module m; - auto func_sym = m.RegisterSymbol("func"); + auto func_sym = mod.RegisterSymbol("func"); VariableList params; params.push_back(create(Source{}, "var", StorageClass::kNone, &i32, @@ -273,8 +264,7 @@ TEST_F(FunctionTest, IsValid_NullParam) { type::Void void_type; type::I32 i32; - Module m; - auto func_sym = m.RegisterSymbol("func"); + auto func_sym = mod.RegisterSymbol("func"); VariableList params; params.push_back(create(Source{}, "var", StorageClass::kNone, &i32, @@ -290,8 +280,7 @@ TEST_F(FunctionTest, IsValid_NullParam) { TEST_F(FunctionTest, IsValid_InvalidParam) { type::Void void_type; - Module m; - auto func_sym = m.RegisterSymbol("func"); + auto func_sym = mod.RegisterSymbol("func"); VariableList params; params.push_back(create(Source{}, "var", StorageClass::kNone, @@ -307,8 +296,7 @@ TEST_F(FunctionTest, IsValid_NullBodyStatement) { type::Void void_type; type::I32 i32; - Module m; - auto func_sym = m.RegisterSymbol("func"); + auto func_sym = mod.RegisterSymbol("func"); VariableList params; params.push_back(create(Source{}, "var", StorageClass::kNone, &i32, @@ -329,8 +317,7 @@ TEST_F(FunctionTest, IsValid_InvalidBodyStatement) { type::Void void_type; type::I32 i32; - Module m; - auto func_sym = m.RegisterSymbol("func"); + auto func_sym = mod.RegisterSymbol("func"); VariableList params; params.push_back(create(Source{}, "var", StorageClass::kNone, &i32, @@ -350,8 +337,7 @@ TEST_F(FunctionTest, ToStr) { type::Void void_type; type::I32 i32; - Module m; - auto func_sym = m.RegisterSymbol("func"); + auto func_sym = mod.RegisterSymbol("func"); auto* body = create(); body->append(create()); @@ -361,7 +347,7 @@ TEST_F(FunctionTest, ToStr) { std::ostringstream out; f.to_str(out, 2); - EXPECT_EQ(out.str(), R"( Function tint_symbol_1 -> __void + EXPECT_EQ(demangle(out.str()), R"( Function func -> __void () { Discard{} @@ -373,8 +359,7 @@ TEST_F(FunctionTest, ToStr_WithDecoration) { type::Void void_type; type::I32 i32; - Module m; - auto func_sym = m.RegisterSymbol("func"); + auto func_sym = mod.RegisterSymbol("func"); auto* body = create(); body->append(create()); @@ -385,7 +370,7 @@ TEST_F(FunctionTest, ToStr_WithDecoration) { std::ostringstream out; f.to_str(out, 2); - EXPECT_EQ(out.str(), R"( Function tint_symbol_1 -> __void + EXPECT_EQ(demangle(out.str()), R"( Function func -> __void WorkgroupDecoration{2 4 6} () { @@ -398,8 +383,7 @@ TEST_F(FunctionTest, ToStr_WithParams) { type::Void void_type; type::I32 i32; - Module m; - auto func_sym = m.RegisterSymbol("func"); + auto func_sym = mod.RegisterSymbol("func"); VariableList params; params.push_back(create(Source{}, "var", StorageClass::kNone, &i32, @@ -414,7 +398,7 @@ TEST_F(FunctionTest, ToStr_WithParams) { std::ostringstream out; f.to_str(out, 2); - EXPECT_EQ(out.str(), R"( Function tint_symbol_1 -> __void + EXPECT_EQ(demangle(out.str()), R"( Function func -> __void ( Variable{ var @@ -431,8 +415,7 @@ TEST_F(FunctionTest, ToStr_WithParams) { TEST_F(FunctionTest, TypeName) { type::Void void_type; - Module m; - auto func_sym = m.RegisterSymbol("func"); + auto func_sym = mod.RegisterSymbol("func"); Function f(Source{}, func_sym, "func", {}, &void_type, create(), FunctionDecorationList{}); @@ -444,8 +427,7 @@ TEST_F(FunctionTest, TypeName_WithParams) { type::I32 i32; type::F32 f32; - Module m; - auto func_sym = m.RegisterSymbol("func"); + auto func_sym = mod.RegisterSymbol("func"); VariableList params; params.push_back(create(Source{}, "var1", StorageClass::kNone, &i32, @@ -463,8 +445,7 @@ TEST_F(FunctionTest, TypeName_WithParams) { TEST_F(FunctionTest, GetLastStatement) { type::Void void_type; - Module m; - auto func_sym = m.RegisterSymbol("func"); + auto func_sym = mod.RegisterSymbol("func"); VariableList params; auto* body = create(); @@ -479,8 +460,7 @@ TEST_F(FunctionTest, GetLastStatement) { TEST_F(FunctionTest, GetLastStatement_nullptr) { type::Void void_type; - Module m; - auto func_sym = m.RegisterSymbol("func"); + auto func_sym = mod.RegisterSymbol("func"); VariableList params; auto* body = create(); @@ -493,8 +473,7 @@ TEST_F(FunctionTest, GetLastStatement_nullptr) { TEST_F(FunctionTest, WorkgroupSize_NoneSet) { type::Void void_type; - Module m; - auto func_sym = m.RegisterSymbol("func"); + auto func_sym = mod.RegisterSymbol("func"); Function f(Source{}, func_sym, "func", {}, &void_type, create(), FunctionDecorationList{}); @@ -510,8 +489,7 @@ TEST_F(FunctionTest, WorkgroupSize_NoneSet) { TEST_F(FunctionTest, WorkgroupSize) { type::Void void_type; - Module m; - auto func_sym = m.RegisterSymbol("func"); + auto func_sym = mod.RegisterSymbol("func"); Function f(Source{}, func_sym, "func", {}, &void_type, create(), diff --git a/src/ast/test_helper.h b/src/ast/test_helper.h index bb558e2652..126171f5c0 100644 --- a/src/ast/test_helper.h +++ b/src/ast/test_helper.h @@ -20,6 +20,7 @@ #include "gtest/gtest.h" #include "src/ast/module.h" +#include "src/demangler.h" namespace tint { namespace ast { @@ -40,8 +41,17 @@ class TestHelperBase : public BASE { return mod.create(std::forward(args)...); } + /// Demangles the given string + /// @param s the string to demangle + /// @returns the demangled string + std::string demangle(const std::string& s) { + return demanger.Demangle(mod, s); + } + /// The module Module mod; + /// A demangler + Demangler demanger; }; using TestHelper = TestHelperBase; diff --git a/src/demangler.cc b/src/demangler.cc new file mode 100644 index 0000000000..c874d26829 --- /dev/null +++ b/src/demangler.cc @@ -0,0 +1,58 @@ +// Copyright 2020 The Tint Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "src/demangler.h" + +namespace tint { +namespace { + +constexpr char kSymbol[] = "tint_symbol_"; +constexpr size_t kSymbolLen = sizeof(kSymbol) - 1; + +} // namespace + +Demangler::Demangler() = default; + +Demangler::~Demangler() = default; + +std::string Demangler::Demangle(const ast::Module& mod, + const std::string& str) const { + auto ret = str; + + size_t pos = 0; + for (;;) { + auto idx = ret.find(kSymbol, pos); + if (idx == std::string::npos) + break; + + auto start_idx = idx + kSymbolLen; + auto end_idx = start_idx; + while (ret[end_idx] >= '0' && ret[end_idx] <= '9') { + end_idx++; + } + auto len = end_idx - start_idx; + + auto id = ret.substr(start_idx, len); + + Symbol sym(std::stoi(id)); + auto name = mod.SymbolToName(sym); + ret.replace(idx, end_idx - idx, name); + + pos = idx + name.length(); + } + + return ret; +} + +} // namespace tint diff --git a/src/demangler.h b/src/demangler.h new file mode 100644 index 0000000000..23f9a2ea75 --- /dev/null +++ b/src/demangler.h @@ -0,0 +1,41 @@ +// Copyright 2020 The Tint Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SRC_DEMANGLER_H_ +#define SRC_DEMANGLER_H_ + +#include + +#include "src/ast/module.h" + +namespace tint { + +/// Helper to demangle strings and replace symbols with original names +class Demangler { + public: + /// Constructor + Demangler(); + /// Destructor + ~Demangler(); + + /// Transforms given string and replaces any symbols with original names + /// @param mod the module where the symbols are registered + /// @param str the string to replace + /// @returns the string with any symbol replacements performed. + std::string Demangle(const ast::Module& mod, const std::string& str) const; +}; + +} // namespace tint + +#endif // SRC_DEMANGLER_H_ diff --git a/src/demangler_test.cc b/src/demangler_test.cc new file mode 100644 index 0000000000..cc0477c531 --- /dev/null +++ b/src/demangler_test.cc @@ -0,0 +1,52 @@ +// Copyright 2020 The Tint Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "src/demangler.h" + +#include "gtest/gtest.h" + +namespace tint { +namespace { + +using DemanglerTest = testing::Test; + +TEST_F(DemanglerTest, NoSymbols) { + ast::Module m; + m.RegisterSymbol("sym1"); + + Demangler d; + EXPECT_EQ("test str", d.Demangle(m, "test str")); +} + +TEST_F(DemanglerTest, Symbol) { + ast::Module m; + m.RegisterSymbol("sym1"); + + Demangler d; + EXPECT_EQ("test sym1 str", d.Demangle(m, "test tint_symbol_1 str")); +} + +TEST_F(DemanglerTest, MultipleSymbols) { + ast::Module m; + m.RegisterSymbol("sym1"); + m.RegisterSymbol("sym2"); + + Demangler d; + EXPECT_EQ( + "test sym1 sym2 sym1 str", + d.Demangle(m, "test tint_symbol_1 tint_symbol_2 tint_symbol_1 str")); +} + +} // namespace +} // namespace tint diff --git a/src/transform/first_index_offset_test.cc b/src/transform/first_index_offset_test.cc index 7a275577e8..20fbb75c15 100644 --- a/src/transform/first_index_offset_test.cc +++ b/src/transform/first_index_offset_test.cc @@ -33,6 +33,7 @@ #include "src/ast/type/u32_type.h" #include "src/ast/variable.h" #include "src/ast/variable_decoration.h" +#include "src/demangler.h" #include "src/diagnostic/formatter.h" #include "src/source.h" #include "src/transform/manager.h" @@ -154,7 +155,7 @@ TEST_F(FirstIndexOffsetTest, BasicModuleVertexIndex) { uniform __struct_TintFirstIndexOffsetData } - Function tint_symbol_1 -> __u32 + Function test -> __u32 () { VariableDeclStatement{ @@ -182,7 +183,7 @@ TEST_F(FirstIndexOffsetTest, BasicModuleVertexIndex) { } } )"; - EXPECT_EQ(got, expected); + EXPECT_EQ(Demangler().Demangle(result.module, got), expected); } TEST_F(FirstIndexOffsetTest, BasicModuleInstanceIndex) { @@ -229,7 +230,7 @@ TEST_F(FirstIndexOffsetTest, BasicModuleInstanceIndex) { uniform __struct_TintFirstIndexOffsetData } - Function tint_symbol_1 -> __u32 + Function test -> __u32 () { VariableDeclStatement{ @@ -257,7 +258,7 @@ TEST_F(FirstIndexOffsetTest, BasicModuleInstanceIndex) { } } )"; - EXPECT_EQ(got, expected); + EXPECT_EQ(Demangler().Demangle(result.module, got), expected); } TEST_F(FirstIndexOffsetTest, BasicModuleBothIndex) { @@ -317,7 +318,7 @@ TEST_F(FirstIndexOffsetTest, BasicModuleBothIndex) { uniform __struct_TintFirstIndexOffsetData } - Function tint_symbol_1 -> __u32 + Function test -> __u32 () { Return{ @@ -328,7 +329,7 @@ TEST_F(FirstIndexOffsetTest, BasicModuleBothIndex) { } } )"; - EXPECT_EQ(got, expected); + EXPECT_EQ(Demangler().Demangle(result.module, got), expected); EXPECT_TRUE(transform_ptr->HasVertexIndex()); EXPECT_EQ(transform_ptr->GetFirstVertexOffset(), 0u); @@ -389,7 +390,7 @@ TEST_F(FirstIndexOffsetTest, NestedCalls) { uniform __struct_TintFirstIndexOffsetData } - Function tint_symbol_1 -> __u32 + Function func1 -> __u32 () { VariableDeclStatement{ @@ -415,7 +416,7 @@ TEST_F(FirstIndexOffsetTest, NestedCalls) { } } } - Function tint_symbol_2 -> __u32 + Function func2 -> __u32 () { Return{ @@ -430,7 +431,7 @@ TEST_F(FirstIndexOffsetTest, NestedCalls) { } } )"; - EXPECT_EQ(got, expected); + EXPECT_EQ(Demangler().Demangle(result.module, got), expected); } } // namespace