Add reader::spv::SuggestSanitizedName

Bug: tint:3
Change-Id: Ie53bbb7a0b2523a2098b485b6a5bb3d5fa4e52f9
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/17422
Reviewed-by: dan sinclair <dsinclair@google.com>
diff --git a/src/reader/spirv/namer.cc b/src/reader/spirv/namer.cc
index a864a35..d2353b4 100644
--- a/src/reader/spirv/namer.cc
+++ b/src/reader/spirv/namer.cc
@@ -76,6 +76,15 @@
   return true;
 }
 
+bool Namer::SuggestSanitizedName(uint32_t id,
+                                 const std::string& suggested_name) {
+  if (HasName(id)) {
+    return false;
+  }
+
+  return SaveName(id, FindUnusedDerivedName(Sanitize(suggested_name)));
+}
+
 }  // namespace spirv
 }  // namespace reader
 }  // namespace tint
diff --git a/src/reader/spirv/namer.h b/src/reader/spirv/namer.h
index ede1c7a..3c9d455 100644
--- a/src/reader/spirv/namer.h
+++ b/src/reader/spirv/namer.h
@@ -75,6 +75,13 @@
   /// @returns true if the ID did not have a previously registered name.
   bool SaveName(uint32_t id, const std::string& name);
 
+  /// Saves a sanitized name for the given ID, if that ID does not yet
+  /// have a registered name.
+  /// @param id the SPIR-V ID
+  /// @param suggested_name the suggested name
+  /// @returns true if a name was newly registered for the ID
+  bool SuggestSanitizedName(uint32_t id, const std::string& suggested_name);
+
  private:
   FailStream fail_stream_;
 
diff --git a/src/reader/spirv/namer_test.cc b/src/reader/spirv/namer_test.cc
index d2a8373..e744a9d 100644
--- a/src/reader/spirv/namer_test.cc
+++ b/src/reader/spirv/namer_test.cc
@@ -143,6 +143,38 @@
   EXPECT_FALSE(error().empty());
 }
 
+TEST_F(SpvNamerTest, SuggestSanitizedName_TakeSuggestionWhenNoConflict) {
+  Namer namer(fail_stream_);
+
+  EXPECT_TRUE(namer.SuggestSanitizedName(1, "father"));
+  EXPECT_THAT(namer.GetName(1), Eq("father"));
+}
+
+TEST_F(SpvNamerTest,
+       SuggestSanitizedName_RejectSuggestionWhenConflictOnSameId) {
+  Namer namer(fail_stream_);
+
+  namer.SaveName(1, "lennon");
+  EXPECT_FALSE(namer.SuggestSanitizedName(1, "mccartney"));
+  EXPECT_THAT(namer.GetName(1), Eq("lennon"));
+}
+
+TEST_F(SpvNamerTest, SuggestSanitizedName_SanitizeSuggestion) {
+  Namer namer(fail_stream_);
+
+  EXPECT_TRUE(namer.SuggestSanitizedName(9, "m:kenzie"));
+  EXPECT_THAT(namer.GetName(9), Eq("m_kenzie"));
+}
+
+TEST_F(SpvNamerTest,
+       SuggestSanitizedName_GenerateNewNameWhenConflictOnDifferentId) {
+  Namer namer(fail_stream_);
+
+  namer.SaveName(7, "rice");
+  EXPECT_TRUE(namer.SuggestSanitizedName(9, "rice"));
+  EXPECT_THAT(namer.GetName(9), Eq("rice_1"));
+}
+
 }  // namespace
 }  // namespace spirv
 }  // namespace reader