sgraenitz created this revision.
sgraenitz added reviewers: erik.pilkington, friss, jingham, JDevlieghere.
Herald added subscribers: chrib, kristof.beyls.
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
https://reviews.llvm.org/D50587
Files:
source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
Index: source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
===================================================================
--- source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -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,51 @@
static ConstString SubsPrimitiveParmItanium(llvm::StringRef mangled,
llvm::StringRef search,
llvm::StringRef replace) {
- Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE);
-
- const size_t max_len =
- mangled.size() + mangled.count(search) * replace.size() + 1;
+ struct SwapParms {
+ llvm::StringRef mangled;
+ llvm::StringRef search;
+ llvm::StringRef replace;
+ ptrdiff_t read_pos;
+ std::back_insert_iterator<std::string> writer;
+
+ SwapParms(llvm::StringRef m, llvm::StringRef s, llvm::StringRef r,
+ std::back_insert_iterator<std::string> w)
+ : mangled(m), search(s), replace(r), read_pos(0), writer(w) {}
+
+ void Substitude(llvm::StringRef tail) {
+ if (tail.startswith(search)) {
+ ptrdiff_t read_len = tail.data() - mangled.data();
+ auto reader = mangled.begin() + 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();
+ }
+ }
- // 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());
+ static void Hook(void *context, const char *match) {
+ ((SwapParms *)context)->Substitude(llvm::StringRef(match));
}
};
// FastDemangle will call our hook 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);
+ std::string output_buf;
+ SwapParms context(mangled, search, replace, std::back_inserter(output_buf));
+ assert(mangled.data()[mangled.size()] == '\0' && "Expect C-String");
+ bool err = llvm::itaniumFindTypesInMangledName(mangled.data(), &context,
+ SwapParms::Hook);
+
+ if (Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)) {
+ if (err)
+ LLDB_LOG(log, "Substituted mangling {0} -> {1}", mangled, output_buf);
+ else
+ LLDB_LOG(log, "Failed to substitute mangling in {0}", mangled);
+ }
- return output_buf == mangled ? ConstString() : ConstString(output_buf);
+ return ConstString(output_buf);
}
uint32_t CPlusPlusLanguage::FindAlternateFunctionManglings(
_______________________________________________
lldb-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits