[llvm] [llvm][Support] fix convertToSnakeFromCamelCase (PR #68375)

Maksim Levental via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 6 11:52:21 PDT 2023


https://github.com/makslevental updated https://github.com/llvm/llvm-project/pull/68375

>From 84ac205bfabea45eafb72e0efe01e8840b023aa6 Mon Sep 17 00:00:00 2001
From: max <maksim.levental at gmail.com>
Date: Thu, 5 Oct 2023 21:00:37 -0500
Subject: [PATCH 1/3] [llvm][Support] fix convertToSnakeFromCamelCase

---
 llvm/lib/Support/StringExtras.cpp       | 18 +++++++-----------
 llvm/unittests/ADT/StringExtrasTest.cpp |  5 +++++
 2 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/llvm/lib/Support/StringExtras.cpp b/llvm/lib/Support/StringExtras.cpp
index 5683d7005584eb2..fd5a34fb3d6e82c 100644
--- a/llvm/lib/Support/StringExtras.cpp
+++ b/llvm/lib/Support/StringExtras.cpp
@@ -12,6 +12,7 @@
 
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Regex.h"
 #include "llvm/Support/raw_ostream.h"
 #include <cctype>
 
@@ -96,18 +97,13 @@ std::string llvm::convertToSnakeFromCamelCase(StringRef input) {
   if (input.empty())
     return "";
 
-  std::string snakeCase;
-  snakeCase.reserve(input.size());
-  for (char c : input) {
-    if (!std::isupper(c)) {
-      snakeCase.push_back(c);
-      continue;
-    }
-
-    if (!snakeCase.empty() && snakeCase.back() != '_')
-      snakeCase.push_back('_');
-    snakeCase.push_back(llvm::toLower(c));
+  std::string snakeCase = input.str();
+  for (int i = 0; i < 10; ++i) {
+    snakeCase = llvm::Regex("([A-Z]+)([A-Z][a-z])").sub("\\1_\\2", snakeCase);
+    snakeCase = llvm::Regex("([a-z0-9])([A-Z])").sub("\\1_\\2", snakeCase);
   }
+  std::transform(snakeCase.begin(), snakeCase.end(), snakeCase.begin(),
+                 [](unsigned char c) { return std::tolower(c); });
   return snakeCase;
 }
 
diff --git a/llvm/unittests/ADT/StringExtrasTest.cpp b/llvm/unittests/ADT/StringExtrasTest.cpp
index 3f69c91b270a355..fab562f1ed0d594 100644
--- a/llvm/unittests/ADT/StringExtrasTest.cpp
+++ b/llvm/unittests/ADT/StringExtrasTest.cpp
@@ -184,6 +184,11 @@ TEST(StringExtrasTest, ConvertToSnakeFromCamelCase) {
 
   testConvertToSnakeCase("OpName", "op_name");
   testConvertToSnakeCase("opName", "op_name");
+  testConvertToSnakeCase("OPName", "op_name");
+  testConvertToSnakeCase("opNAME", "op_name");
+  testConvertToSnakeCase("opNAMe", "op_na_me");
+  testConvertToSnakeCase("opnameE", "opname_e");
+  testConvertToSnakeCase("OPNameOPName", "op_name_op_name");
   testConvertToSnakeCase("_OpName", "_op_name");
   testConvertToSnakeCase("Op_Name", "op_name");
   testConvertToSnakeCase("", "");

>From f005c3b9a92239d1335ab42fec77c005c350be88 Mon Sep 17 00:00:00 2001
From: max <maksim.levental at gmail.com>
Date: Fri, 6 Oct 2023 12:39:35 -0500
Subject: [PATCH 2/3] hoist regexes

---
 llvm/lib/Support/StringExtras.cpp       | 7 +++++--
 llvm/unittests/ADT/StringExtrasTest.cpp | 1 +
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Support/StringExtras.cpp b/llvm/lib/Support/StringExtras.cpp
index fd5a34fb3d6e82c..dce429a4eeaad68 100644
--- a/llvm/lib/Support/StringExtras.cpp
+++ b/llvm/lib/Support/StringExtras.cpp
@@ -97,10 +97,13 @@ std::string llvm::convertToSnakeFromCamelCase(StringRef input) {
   if (input.empty())
     return "";
 
+  llvm::Regex trailingCap = llvm::Regex("([A-Z]+)([A-Z][a-z])");
+  llvm::Regex leadingCap = llvm::Regex("([a-z0-9])([A-Z])");
+
   std::string snakeCase = input.str();
   for (int i = 0; i < 10; ++i) {
-    snakeCase = llvm::Regex("([A-Z]+)([A-Z][a-z])").sub("\\1_\\2", snakeCase);
-    snakeCase = llvm::Regex("([a-z0-9])([A-Z])").sub("\\1_\\2", snakeCase);
+    snakeCase = trailingCap.sub("\\1_\\2", snakeCase);
+    snakeCase = leadingCap.sub("\\1_\\2", snakeCase);
   }
   std::transform(snakeCase.begin(), snakeCase.end(), snakeCase.begin(),
                  [](unsigned char c) { return std::tolower(c); });
diff --git a/llvm/unittests/ADT/StringExtrasTest.cpp b/llvm/unittests/ADT/StringExtrasTest.cpp
index fab562f1ed0d594..522daea5780f955 100644
--- a/llvm/unittests/ADT/StringExtrasTest.cpp
+++ b/llvm/unittests/ADT/StringExtrasTest.cpp
@@ -185,6 +185,7 @@ TEST(StringExtrasTest, ConvertToSnakeFromCamelCase) {
   testConvertToSnakeCase("OpName", "op_name");
   testConvertToSnakeCase("opName", "op_name");
   testConvertToSnakeCase("OPName", "op_name");
+  testConvertToSnakeCase("Intel_OCL_BI", "intel_ocl_bi");
   testConvertToSnakeCase("opNAME", "op_name");
   testConvertToSnakeCase("opNAMe", "op_na_me");
   testConvertToSnakeCase("opnameE", "opname_e");

>From d131ddbf6841cbd1a1db631b6c3c00b0c9def700 Mon Sep 17 00:00:00 2001
From: max <maksim.levental at gmail.com>
Date: Fri, 6 Oct 2023 13:30:00 -0500
Subject: [PATCH 3/3] make fixed-point

---
 llvm/lib/Support/StringExtras.cpp | 24 +++++++++++++++++-------
 1 file changed, 17 insertions(+), 7 deletions(-)

diff --git a/llvm/lib/Support/StringExtras.cpp b/llvm/lib/Support/StringExtras.cpp
index dce429a4eeaad68..69bd91506aff884 100644
--- a/llvm/lib/Support/StringExtras.cpp
+++ b/llvm/lib/Support/StringExtras.cpp
@@ -12,6 +12,7 @@
 
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/Regex.h"
 #include "llvm/Support/raw_ostream.h"
 #include <cctype>
@@ -100,14 +101,23 @@ std::string llvm::convertToSnakeFromCamelCase(StringRef input) {
   llvm::Regex trailingCap = llvm::Regex("([A-Z]+)([A-Z][a-z])");
   llvm::Regex leadingCap = llvm::Regex("([a-z0-9])([A-Z])");
 
-  std::string snakeCase = input.str();
-  for (int i = 0; i < 10; ++i) {
-    snakeCase = trailingCap.sub("\\1_\\2", snakeCase);
-    snakeCase = leadingCap.sub("\\1_\\2", snakeCase);
-  }
-  std::transform(snakeCase.begin(), snakeCase.end(), snakeCase.begin(),
+  std::string curr = input.str();
+  std::string prev = input.str();
+  size_t iters = 0;
+  do {
+    prev = curr;
+    curr = trailingCap.sub("\\1_\\2", prev);
+    curr = leadingCap.sub("\\1_\\2", curr);
+  } while (curr != prev && ++iters < input.size());
+
+  if (iters == input.size())
+    llvm::report_fatal_error(
+        input + Twine(" couldn't be converted to snake case after ") +
+        Twine(iters) + Twine("iterations."));
+
+  std::transform(curr.begin(), curr.end(), curr.begin(),
                  [](unsigned char c) { return std::tolower(c); });
-  return snakeCase;
+  return curr;
 }
 
 std::string llvm::convertToCamelFromSnakeCase(StringRef input,



More information about the llvm-commits mailing list