Update namer to use symbol table.
This Cl updates the various namer objects to work off the symbol table
instead of names.
Change-Id: I94b00a10225d0587f037cfaa6d9b42e2a8885734
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/35101
Reviewed-by: Ben Clayton <bclayton@google.com>
Commit-Queue: dan sinclair <dsinclair@chromium.org>
Auto-Submit: dan sinclair <dsinclair@chromium.org>
diff --git a/src/ast/module.cc b/src/ast/module.cc
index 1e458c0..5dcc12b 100644
--- a/src/ast/module.cc
+++ b/src/ast/module.cc
@@ -81,6 +81,10 @@
return symbol_table_.Register(name);
}
+std::string Module::SymbolToName(const Symbol sym) const {
+ return symbol_table_.NameFor(sym);
+}
+
bool Module::IsValid() const {
for (auto* var : global_variables_) {
if (var == nullptr || !var->IsValid()) {
diff --git a/src/ast/module.h b/src/ast/module.h
index 59a67b0..b274be1 100644
--- a/src/ast/module.h
+++ b/src/ast/module.h
@@ -169,6 +169,11 @@
/// previously generated symbol will be returned.
Symbol RegisterSymbol(const std::string& name);
+ /// Returns the `name` for `sym`
+ /// @param sym the symbol to retrieve the name for
+ /// @returns the use provided `name` for the symbol or "" if not found
+ std::string SymbolToName(const Symbol sym) const;
+
private:
Module(const Module&) = delete;
diff --git a/src/namer.cc b/src/namer.cc
index 54c17ad..f5f5600 100644
--- a/src/namer.cc
+++ b/src/namer.cc
@@ -18,46 +18,44 @@
#include <iomanip>
#include <sstream>
+#include "src/symbol.h"
+
namespace tint {
-Namer::Namer() = default;
+Namer::Namer(ast::Module* mod) : module_(mod) {}
Namer::~Namer() = default;
-bool Namer::IsMapped(const std::string& name) {
- auto it = name_map_.find(name);
- return it != name_map_.end();
+bool Namer::IsUsed(const std::string& name) {
+ auto it = used_.find(name);
+ return it != used_.end();
}
-HashingNamer::HashingNamer() = default;
-
-HashingNamer::~HashingNamer() = default;
-
-std::string HashingNamer::NameFor(const std::string& name) {
- auto it = name_map_.find(name);
- if (it != name_map_.end()) {
- return it->second;
+std::string Namer::GenerateName(const std::string& prefix) {
+ std::string name = prefix;
+ uint32_t i = 0;
+ while (IsUsed(name)) {
+ name = prefix + "_" + std::to_string(i);
+ ++i;
}
-
- std::stringstream ret_name;
- ret_name << "tint_";
-
- ret_name << std::hex << std::setfill('0') << std::setw(2);
- for (size_t i = 0; i < name.size(); ++i) {
- ret_name << static_cast<uint32_t>(name[i]);
- }
-
- name_map_[name] = ret_name.str();
- return ret_name.str();
-}
-
-NoopNamer::NoopNamer() = default;
-
-NoopNamer::~NoopNamer() = default;
-
-std::string NoopNamer::NameFor(const std::string& name) {
- name_map_[name] = name;
+ used_.insert(name);
return name;
}
+MangleNamer::MangleNamer(ast::Module* mod) : Namer(mod) {}
+
+MangleNamer::~MangleNamer() = default;
+
+std::string MangleNamer::NameFor(const Symbol& sym) {
+ return sym.to_str();
+}
+
+UnsafeNamer::UnsafeNamer(ast::Module* mod) : Namer(mod) {}
+
+UnsafeNamer::~UnsafeNamer() = default;
+
+std::string UnsafeNamer::NameFor(const Symbol& sym) {
+ return module_->SymbolToName(sym);
+}
+
} // namespace tint
diff --git a/src/namer.h b/src/namer.h
index 28a8de4..8d05eb2 100644
--- a/src/namer.h
+++ b/src/namer.h
@@ -19,52 +19,73 @@
#include <unordered_map>
#include <unordered_set>
+#include "src/ast/module.h"
+
namespace tint {
/// Base class for the namers.
class Namer {
public:
/// Constructor
- Namer();
+ /// @param mod the module this namer works with
+ explicit Namer(ast::Module* mod);
+ /// Destructor
virtual ~Namer();
- /// Returns a sanitized version of `name`
- /// @param name the name to sanitize
- /// @returns the sanitized version of `name`
- virtual std::string NameFor(const std::string& name) = 0;
+ /// Returns the name for `sym`
+ /// @param sym the symbol to retrieve the name for
+ /// @returns the sanitized version of `name` or "" if not found
+ virtual std::string NameFor(const Symbol& sym) = 0;
- /// Returns if the given name has been mapped already
- /// @param name the name to check
- /// @returns true if the name has been mapped
- bool IsMapped(const std::string& name);
+ /// Generates a unique name for `prefix`
+ /// @param prefix the prefix name
+ /// @returns the unique name string
+ std::string GenerateName(const std::string& prefix);
protected:
- /// Map of original name to new name.
- std::unordered_map<std::string, std::string> name_map_;
+ /// Checks if `name` has been used
+ /// @param name the name to check
+ /// @returns true if `name` has already been used
+ bool IsUsed(const std::string& name);
+
+ /// The module storing the symbol table
+ ast::Module* module_ = nullptr;
+
+ private:
+ // The list of names taken by the remapper
+ std::unordered_set<std::string> used_;
};
-/// A namer class which hashes the name
-class HashingNamer : public Namer {
+/// A namer class which mangles the name
+class MangleNamer : public Namer {
public:
- HashingNamer();
- ~HashingNamer() override;
+ /// Constructor
+ /// @param mod the module to retrieve names from
+ explicit MangleNamer(ast::Module* mod);
+ /// Destructor
+ ~MangleNamer() override;
- /// Returns a sanitized version of `name`
- /// @param name the name to sanitize
- /// @returns the sanitized version of `name`
- std::string NameFor(const std::string& name) override;
+ /// Returns a mangled name for `sym`
+ /// @param sym the symbol to name
+ /// @returns the name for `sym` or "" if not found
+ std::string NameFor(const Symbol& sym) override;
};
-/// A namer which just returns the provided string
-class NoopNamer : public Namer {
+/// A namer which returns the user provided name. This is unsafe in general as
+/// it passes user provided data through to the backend compiler. It is useful
+/// for development and debugging.
+class UnsafeNamer : public Namer {
public:
- NoopNamer();
- ~NoopNamer() override;
+ /// Constructor
+ /// @param mod the module to retrieve names from
+ explicit UnsafeNamer(ast::Module* mod);
+ /// Destructor
+ ~UnsafeNamer() override;
/// Returns `name`
- /// @param name the name
- /// @returns `name`
- std::string NameFor(const std::string& name) override;
+ /// @param sym the symbol
+ /// @returns `name` or "" if not found
+ std::string NameFor(const Symbol& sym) override;
};
} // namespace tint
diff --git a/src/namer_test.cc b/src/namer_test.cc
index bc3bbbd..5a318f7 100644
--- a/src/namer_test.cc
+++ b/src/namer_test.cc
@@ -15,50 +15,49 @@
#include "src/namer.h"
#include "gtest/gtest.h"
+#include "src/ast/module.h"
namespace tint {
namespace {
-using Namer_HashingNamer_Test = testing::Test;
+using NamerTest = testing::Test;
-TEST_F(Namer_HashingNamer_Test, ReturnsName) {
- HashingNamer n;
- EXPECT_EQ("tint_6d795f6e616d65", n.NameFor("my_name"));
+TEST_F(NamerTest, GenerateName) {
+ ast::Module m;
+ MangleNamer n(&m);
+ EXPECT_EQ("name", n.GenerateName("name"));
+ EXPECT_EQ("name_0", n.GenerateName("name"));
+ EXPECT_EQ("name_1", n.GenerateName("name"));
}
-TEST_F(Namer_HashingNamer_Test, ReturnsSameValueForSameName) {
- HashingNamer n;
- EXPECT_EQ("tint_6e616d6531", n.NameFor("name1"));
- EXPECT_EQ("tint_6e616d6532", n.NameFor("name2"));
- EXPECT_EQ("tint_6e616d6531", n.NameFor("name1"));
+using MangleNamerTest = testing::Test;
+
+TEST_F(MangleNamerTest, ReturnsName) {
+ ast::Module m;
+ auto s = m.RegisterSymbol("my_sym");
+
+ MangleNamer n(&m);
+ EXPECT_EQ("tint_symbol_1", n.NameFor(s));
}
-TEST_F(Namer_HashingNamer_Test, IsMapped) {
- HashingNamer n;
- EXPECT_FALSE(n.IsMapped("my_name"));
- EXPECT_EQ("tint_6d795f6e616d65", n.NameFor("my_name"));
- EXPECT_TRUE(n.IsMapped("my_name"));
+TEST_F(MangleNamerTest, ReturnsSameValueForSameName) {
+ ast::Module m;
+ auto s1 = m.RegisterSymbol("my_sym");
+ auto s2 = m.RegisterSymbol("my_sym2");
+
+ MangleNamer n(&m);
+ EXPECT_EQ("tint_symbol_1", n.NameFor(s1));
+ EXPECT_EQ("tint_symbol_2", n.NameFor(s2));
+ EXPECT_EQ("tint_symbol_1", n.NameFor(s1));
}
-using Namer_NoopNamer_Test = testing::Test;
+using UnsafeNamerTest = testing::Test;
+TEST_F(UnsafeNamerTest, ReturnsName) {
+ ast::Module m;
+ auto s = m.RegisterSymbol("my_sym");
-TEST_F(Namer_NoopNamer_Test, ReturnsName) {
- NoopNamer n;
- EXPECT_EQ("my_name", n.NameFor("my_name"));
-}
-
-TEST_F(Namer_NoopNamer_Test, ReturnsSameValueForSameName) {
- NoopNamer n;
- EXPECT_EQ("name1", n.NameFor("name1"));
- EXPECT_EQ("name2", n.NameFor("name2"));
- EXPECT_EQ("name1", n.NameFor("name1"));
-}
-
-TEST_F(Namer_NoopNamer_Test, IsMapped) {
- NoopNamer n;
- EXPECT_FALSE(n.IsMapped("my_name"));
- EXPECT_EQ("my_name", n.NameFor("my_name"));
- EXPECT_TRUE(n.IsMapped("my_name"));
+ UnsafeNamer n(&m);
+ EXPECT_EQ("my_sym", n.NameFor(s));
}
} // namespace