Add a demangler

This CL adds a simple demangler to convert the `tint_symbol_YYY` back to
the original symbol name.

Change-Id: I532ed13dc4c52e0f0e3568b8b7d8d0a5c67d8472
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/35440
Commit-Queue: dan sinclair <dsinclair@chromium.org>
Auto-Submit: dan sinclair <dsinclair@chromium.org>
Reviewed-by: Ben Clayton <bclayton@google.com>
This commit is contained in:
dan sinclair 2020-12-11 18:29:03 +00:00 committed by Commit Bot service account
parent a41132fcd8
commit 2d0282b308
8 changed files with 203 additions and 57 deletions

View File

@ -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",

View File

@ -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

View File

@ -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<Variable>(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<Variable>(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<Variable>(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<Variable>(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<BlockStatement>(), 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<Variable>(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<Variable>(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<Variable>(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<Variable>(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<Variable>(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<Variable>(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<Variable>(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<BlockStatement>();
body->append(create<DiscardStatement>());
@ -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<BlockStatement>();
body->append(create<DiscardStatement>());
@ -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<Variable>(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<BlockStatement>(), 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<Variable>(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<BlockStatement>();
@ -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<BlockStatement>();
@ -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<BlockStatement>(), 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<BlockStatement>(),

View File

@ -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<T>(std::forward<ARGS>(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<testing::Test>;

58
src/demangler.cc Normal file
View File

@ -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

41
src/demangler.h Normal file
View File

@ -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 <string>
#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_

52
src/demangler_test.cc Normal file
View File

@ -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

View File

@ -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