[spirv-reader] Add Namer::MakeDerivedName

Bug: tint:3
Change-Id: I4dc3049c577049bb4ad0d1e42ec80f7d82cdb4a4
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/23181
Reviewed-by: dan sinclair <dsinclair@google.com>
diff --git a/src/reader/spirv/namer.cc b/src/reader/spirv/namer.cc
index c0957eb..c5c3fb3 100644
--- a/src/reader/spirv/namer.cc
+++ b/src/reader/spirv/namer.cc
@@ -80,6 +80,13 @@
   return derived_name;
 }
 
+std::string Namer::MakeDerivedName(const std::string& base_name) {
+  auto result = FindUnusedDerivedName(base_name);
+  // Register it.
+  name_to_id_[result] = 0;
+  return result;
+}
+
 bool Namer::SaveName(uint32_t id, const std::string& name) {
   if (HasName(id)) {
     return Fail() << "internal error: ID " << id
diff --git a/src/reader/spirv/namer.h b/src/reader/spirv/namer.h
index e76fc2b..3179dd5 100644
--- a/src/reader/spirv/namer.h
+++ b/src/reader/spirv/namer.h
@@ -89,6 +89,13 @@
   /// @returns a new name
   std::string FindUnusedDerivedName(const std::string& base_name) const;
 
+  /// Returns a newly registered name based on a given base name.
+  /// In the internal table |name_to_id_|, it is mapped to the invalid
+  /// SPIR-V ID 0.  It does not have an entry in |id_to_name_|.
+  /// @param base_name the base name
+  /// @returns a new name
+  std::string MakeDerivedName(const std::string& base_name);
+
   /// Records a mapping from the given ID to a name. Emits a failure
   /// if the ID already has a registered name.
   /// @param id the SPIR-V ID
diff --git a/src/reader/spirv/namer_test.cc b/src/reader/spirv/namer_test.cc
index ef5e4ac..0801593 100644
--- a/src/reader/spirv/namer_test.cc
+++ b/src/reader/spirv/namer_test.cc
@@ -86,6 +86,8 @@
 TEST_F(SpvNamerTest, FindUnusedDerivedName_NoRecordedName) {
   Namer namer(fail_stream_);
   EXPECT_THAT(namer.FindUnusedDerivedName("eleanor"), Eq("eleanor"));
+  // Prove that it wasn't registered when first found.
+  EXPECT_THAT(namer.FindUnusedDerivedName("eleanor"), Eq("eleanor"));
 }
 
 TEST_F(SpvNamerTest, FindUnusedDerivedName_HasRecordedName) {
@@ -103,6 +105,28 @@
   EXPECT_THAT(namer.FindUnusedDerivedName("rigby"), Eq("rigby_2"));
 }
 
+TEST_F(SpvNamerTest, MakeDerivedName_NoRecordedName) {
+  Namer namer(fail_stream_);
+  EXPECT_THAT(namer.MakeDerivedName("eleanor"), Eq("eleanor"));
+  // Prove that it was registered when first found.
+  EXPECT_THAT(namer.MakeDerivedName("eleanor"), Eq("eleanor_1"));
+}
+
+TEST_F(SpvNamerTest, MakeDerivedName_HasRecordedName) {
+  Namer namer(fail_stream_);
+  namer.SaveName(12, "rigby");
+  EXPECT_THAT(namer.MakeDerivedName("rigby"), Eq("rigby_1"));
+}
+
+TEST_F(SpvNamerTest, MakeDerivedName_HasMultipleConflicts) {
+  Namer namer(fail_stream_);
+  namer.SaveName(12, "rigby");
+  namer.SaveName(13, "rigby_1");
+  namer.SaveName(14, "rigby_3");
+  // It picks the first non-conflicting suffix.
+  EXPECT_THAT(namer.MakeDerivedName("rigby"), Eq("rigby_2"));
+}
+
 TEST_F(SpvNamerTest, SaveNameOnce) {
   Namer namer(fail_stream_);