[Lldb-commits] [lldb] r339583 - Straight forward FastDemangle replacement in SubsPrimitiveParmItanium

Stefan Granitz via lldb-commits lldb-commits at lists.llvm.org
Mon Aug 13 09:45:07 PDT 2018


Author: stefan.graenitz
Date: Mon Aug 13 09:45:06 2018
New Revision: 339583

URL: http://llvm.org/viewvc/llvm-project?rev=339583&view=rev
Log:
Straight forward FastDemangle replacement in SubsPrimitiveParmItanium

Summary:
Removing FastDemangle will greatly reduce maintenance efforts. This patch replaces the last point of use in LLDB. Semantics should be kept intact.

Once this is agreed upon, we can:
* Remove the FastDemangle sources
* Add more features e.g. substitutions in template parameters, considering all variations, etc.

Depends on LLVM patch https://reviews.llvm.org/D50586

Reviewers: erik.pilkington, friss, jingham, JDevlieghere

Subscribers: kristof.beyls, chrib, lldb-commits

Differential Revision: https://reviews.llvm.org/D50587

Modified:
    lldb/trunk/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
    lldb/trunk/unittests/Language/CPlusPlus/CPlusPlusLanguageTest.cpp

Modified: lldb/trunk/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp?rev=339583&r1=339582&r2=339583&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp (original)
+++ lldb/trunk/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp Mon Aug 13 09:45:06 2018
@@ -21,6 +21,7 @@
 
 // Other libraries and framework includes
 #include "llvm/ADT/StringRef.h"
+#include "llvm/Demangle/Demangle.h"
 
 // Project includes
 #include "lldb/Core/PluginManager.h"
@@ -30,7 +31,6 @@
 #include "lldb/DataFormatters/FormattersHelpers.h"
 #include "lldb/DataFormatters/VectorType.h"
 #include "lldb/Utility/ConstString.h"
-#include "lldb/Utility/FastDemangle.h"
 #include "lldb/Utility/Log.h"
 #include "lldb/Utility/RegularExpression.h"
 
@@ -278,48 +278,67 @@ bool CPlusPlusLanguage::ExtractContextAn
 static ConstString SubsPrimitiveParmItanium(llvm::StringRef mangled,
                                             llvm::StringRef search,
                                             llvm::StringRef replace) {
-  Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE);
+  class PrimitiveParmSubs {
+    llvm::StringRef mangled;
+    llvm::StringRef search;
+    llvm::StringRef replace;
+    ptrdiff_t read_pos;
+    std::string output;
+    std::back_insert_iterator<std::string> writer;
+
+  public:
+    PrimitiveParmSubs(llvm::StringRef m, llvm::StringRef s, llvm::StringRef r)
+        : mangled(m), search(s), replace(r), read_pos(0),
+          writer(std::back_inserter(output)) {}
+
+    void Substitute(llvm::StringRef tail) {
+      assert(tail.data() >= mangled.data() &&
+             tail.data() < mangled.data() + mangled.size() &&
+             "tail must point into range of mangled");
+
+      if (tail.startswith(search)) {
+        auto reader = mangled.begin() + read_pos;
+        ptrdiff_t read_len = tail.data() - (mangled.data() + read_pos);
+
+        // First write the unmatched part of the original. Then write the
+        // replacement string. Finally skip the search string in the original.
+        writer = std::copy(reader, reader + read_len, writer);
+        writer = std::copy(replace.begin(), replace.end(), writer);
+        read_pos += read_len + search.size();
+      }
+    }
 
-  const size_t max_len =
-      mangled.size() + mangled.count(search) * replace.size() + 1;
+    ConstString Finalize() {
+      // If we did a substitution, write the remaining part of the original.
+      if (read_pos > 0) {
+        writer = std::copy(mangled.begin() + read_pos, mangled.end(), writer);
+        read_pos = mangled.size();
+      }
 
-  // Make a temporary buffer to fix up the mangled parameter types and copy the
-  // original there
-  std::string output_buf;
-  output_buf.reserve(max_len);
-  output_buf.insert(0, mangled.str());
-  ptrdiff_t replaced_offset = 0;
-
-  auto swap_parms_hook = [&](const char *parsee) {
-    if (!parsee || !*parsee)
-      return;
-
-    // Check whether we've found a substitutee
-    llvm::StringRef s(parsee);
-    if (s.startswith(search)) {
-      // account for the case where a replacement is of a different length to
-      // the original
-      replaced_offset += replace.size() - search.size();
-
-      ptrdiff_t replace_idx = (mangled.size() - s.size()) + replaced_offset;
-      output_buf.erase(replace_idx, search.size());
-      output_buf.insert(replace_idx, replace.str());
+      return ConstString(output);
+    }
+
+    static void Callback(void *context, const char *match) {
+      ((PrimitiveParmSubs *)context)->Substitute(llvm::StringRef(match));
     }
   };
 
-  // FastDemangle will call our hook for each instance of a primitive type,
+  // FastDemangle will call back for each instance of a primitive type,
   // allowing us to perform substitution
-  char *const demangled =
-      FastDemangle(mangled.str().c_str(), mangled.size(), swap_parms_hook);
-
-  if (log)
-    log->Printf("substituted mangling for %s:{%s} %s:{%s}\n",
-                mangled.str().c_str(), demangled, output_buf.c_str(),
-                FastDemangle(output_buf.c_str()));
-  // FastDemangle malloc'd this string.
-  free(demangled);
+  PrimitiveParmSubs parmSubs(mangled, search, replace);
+  assert(mangled.data()[mangled.size()] == '\0' && "Expect C-String");
+  bool err = llvm::itaniumFindTypesInMangledName(mangled.data(), &parmSubs,
+                                                 PrimitiveParmSubs::Callback);
+  ConstString result = parmSubs.Finalize();
+
+  if (Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)) {
+    if (err)
+      LLDB_LOG(log, "Failed to substitute mangling in {0}", mangled);
+    else if (result)
+      LLDB_LOG(log, "Substituted mangling {0} -> {1}", mangled, result);
+  }
 
-  return output_buf == mangled ? ConstString() : ConstString(output_buf);
+  return result;
 }
 
 uint32_t CPlusPlusLanguage::FindAlternateFunctionManglings(

Modified: lldb/trunk/unittests/Language/CPlusPlus/CPlusPlusLanguageTest.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/Language/CPlusPlus/CPlusPlusLanguageTest.cpp?rev=339583&r1=339582&r2=339583&view=diff
==============================================================================
--- lldb/trunk/unittests/Language/CPlusPlus/CPlusPlusLanguageTest.cpp (original)
+++ lldb/trunk/unittests/Language/CPlusPlus/CPlusPlusLanguageTest.cpp Mon Aug 13 09:45:06 2018
@@ -183,4 +183,5 @@ TEST(CPlusPlusLanguage, FindAlternateFun
   EXPECT_THAT(FindAlternate("_ZN1A1fEa"), Contains("_ZN1A1fEc"));
   EXPECT_THAT(FindAlternate("_ZN1A1fEx"), Contains("_ZN1A1fEl"));
   EXPECT_THAT(FindAlternate("_ZN1A1fEy"), Contains("_ZN1A1fEm"));
+  EXPECT_THAT(FindAlternate("_ZN1A1fEai"), Contains("_ZN1A1fEci"));
 }




More information about the lldb-commits mailing list