[Lldb-commits] [lldb] [lldb] Move demangling into a minimal D language plugin (PR #232929)

via lldb-commits lldb-commits at lists.llvm.org
Fri Oct 16 13:47:35 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-lldb

Author: Adrian Prantl (adrian-prantl)

<details>
<summary>Changes</summary>

Currently Mangled demangles D names itself, since there is no D
language plugin to hand them to.

This patch adds a minimal one, like the Rust plugin, that recognizes D
source files, registers the D mangling scheme, and demangles its names
with the code that moves out of Mangled, which leaves Mangled without
a demangler of its own.

Assisted-by: Claude

Depends on https://github.com/llvm/llvm-project/pull/232927

---

Patch is 72.29 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/232929.diff


28 Files Affected:

- (modified) lldb/include/lldb/Core/Mangled.h (+61-32) 
- (modified) lldb/include/lldb/Core/Module.h (+3-2) 
- (modified) lldb/include/lldb/Symbol/Symtab.h (+3-3) 
- (modified) lldb/include/lldb/Target/Language.h (+57) 
- (modified) lldb/source/Core/Mangled.cpp (+180-199) 
- (modified) lldb/source/Core/Module.cpp (+12) 
- (modified) lldb/source/Plugins/Language/CMakeLists.txt (+2) 
- (modified) lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp (+177-4) 
- (modified) lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h (+7) 
- (added) lldb/source/Plugins/Language/D/CMakeLists.txt (+11) 
- (added) lldb/source/Plugins/Language/D/DLanguage.cpp (+81) 
- (added) lldb/source/Plugins/Language/D/DLanguage.h (+44) 
- (added) lldb/source/Plugins/Language/Rust/CMakeLists.txt (+11) 
- (added) lldb/source/Plugins/Language/Rust/RustLanguage.cpp (+70) 
- (added) lldb/source/Plugins/Language/Rust/RustLanguage.h (+44) 
- (modified) lldb/source/Symbol/Symtab.cpp (+58-77) 
- (modified) lldb/source/Target/Language.cpp (+24) 
- (modified) lldb/unittests/Core/CMakeLists.txt (+2) 
- (modified) lldb/unittests/Core/MangledTest.cpp (+57-1) 
- (modified) lldb/unittests/Core/ModuleTest.cpp (+51) 
- (modified) lldb/unittests/Language/CMakeLists.txt (+2) 
- (added) lldb/unittests/Language/D/CMakeLists.txt (+6) 
- (added) lldb/unittests/Language/D/DLanguageTest.cpp (+43) 
- (added) lldb/unittests/Language/Rust/CMakeLists.txt (+6) 
- (added) lldb/unittests/Language/Rust/RustLanguageTest.cpp (+35) 
- (modified) lldb/unittests/Symbol/CMakeLists.txt (+1) 
- (modified) lldb/unittests/Symbol/CallEdgeTest.cpp (+2-1) 
- (modified) lldb/unittests/Symbol/TestTypeSystemClang.cpp (+2-1) 


``````````diff
diff --git a/lldb/include/lldb/Core/Mangled.h b/lldb/include/lldb/Core/Mangled.h
index 622c0f82f49f77..b29dd1930d77a5 100644
--- a/lldb/include/lldb/Core/Mangled.h
+++ b/lldb/include/lldb/Core/Mangled.h
@@ -14,9 +14,11 @@
 #include "lldb/lldb-enumerations.h"
 #include "lldb/lldb-forward.h"
 #include "lldb/lldb-types.h"
+#include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/StringRef.h"
 
 #include <cstddef>
+#include <cstdint>
 #include <optional>
 
 namespace lldb_private {
@@ -39,13 +41,41 @@ class Mangled {
     ePreferDemangledWithoutArguments
   };
 
-  enum ManglingScheme {
+  /// The underlying type is fixed so that the schemes that language plugins
+  /// register, which have no enumerators, are valid values too.
+  enum ManglingScheme : uint8_t {
     eManglingSchemeNone = 0,
-    eManglingSchemeMSVC,
-    eManglingSchemeItanium,
-    eManglingSchemeRustV0,
-    eManglingSchemeD,
     eManglingSchemeSwift,
+    /// The first of the schemes that language plugins register with
+    /// RegisterManglingScheme().
+    eFirstRegisteredManglingScheme,
+  };
+
+  /// The number of mangling schemes, including all that can be registered.
+  static constexpr size_t kNumManglingSchemes = 16;
+
+  /// What a mangled function name says about the function's declaration.
+  enum class FunctionNameKind {
+    /// No enclosing context.
+    TopLevel,
+    /// A function in a namespace or module.
+    InNamespace,
+    /// A method.
+    Method,
+    /// A constructor or destructor, so its context is a type.
+    ConstructorOrDestructor,
+    /// A function or method in a context that the mangling doesn't classify.
+    Unknown,
+  };
+
+  /// The parts of a mangled function name that its symbol is indexed by.
+  struct FunctionNameParts {
+    /// If empty, the symbol is only indexed by its mangled name.
+    ConstString basename;
+    /// The enclosing context. Only needed for ConstructorOrDestructor and
+    /// Unknown.
+    ConstString decl_context;
+    FunctionNameKind kind = FunctionNameKind::Unknown;
   };
 
   /// Default constructor.
@@ -195,33 +225,6 @@ class Mangled {
   ///     if there is no mangled or demangled counterpart.
   lldb::LanguageType GuessLanguage() const;
 
-  /// Function signature for filtering mangled names.
-  using SkipMangledNameFn = bool(llvm::StringRef, ManglingScheme);
-
-  /// Get rich mangling information. This is optimized for batch processing
-  /// while populating a name index. To get the pure demangled name string for
-  /// a single entity, use GetDemangledName() instead.
-  ///
-  /// For names that match the Itanium mangling scheme, this uses LLVM's
-  /// ItaniumPartialDemangler. All other names fall back to LLDB's builtin
-  /// parser currently.
-  ///
-  /// This function is thread-safe when used with different \a context
-  /// instances in different threads.
-  ///
-  /// \param[in] context
-  ///     The context for this function. A single instance can be stack-
-  ///     allocated in the caller's frame and used for multiple calls.
-  ///
-  /// \param[in] skip_mangled_name
-  ///     A filtering function for skipping entities based on name and mangling
-  ///     scheme. This can be null if unused.
-  ///
-  /// \return
-  ///     True on success, false otherwise.
-  bool GetRichManglingInfo(RichManglingContext &context,
-                           SkipMangledNameFn *skip_mangled_name);
-
   /// Try to identify the mangling scheme used.
   /// \param[in] name
   ///     The name we are attempting to identify the mangling scheme for.
@@ -233,6 +236,32 @@ class Mangled {
 
   static bool IsMangledName(llvm::StringRef name);
 
+  /// Returns true if \p name, which starts with one of the prefixes of a
+  /// mangling scheme, is a name of that scheme.
+  using ManglingSchemeMatcher = bool (*)(llvm::StringRef name);
+
+  /// Register a mangling scheme whose names start with one of \p prefixes,
+  /// for the language plugin of \p language to demangle and parse. If the
+  /// prefixes alone don't tell the names of the scheme apart, \p matches
+  /// checks the rest of each name. Language plugins call this when they are
+  /// initialized. Registering the same scheme again returns the same scheme.
+  ///
+  /// \return
+  ///     The new scheme, or eManglingSchemeNone if there is no room for
+  ///     another one.
+  static ManglingScheme
+  RegisterManglingScheme(llvm::ArrayRef<llvm::StringRef> prefixes,
+                         lldb::LanguageType language,
+                         ManglingSchemeMatcher matches = nullptr);
+
+  /// Stop recognizing the names of \p scheme, a scheme returned by
+  /// RegisterManglingScheme().
+  static void UnregisterManglingScheme(ManglingScheme scheme);
+
+  /// Returns the language that registered \p scheme, or eLanguageTypeUnknown
+  /// if no language did.
+  static lldb::LanguageType GetLanguageForManglingScheme(ManglingScheme scheme);
+
   /// Decode a serialized version of this object from data.
   ///
   /// \param data
diff --git a/lldb/include/lldb/Core/Module.h b/lldb/include/lldb/Core/Module.h
index e71a29e3e413b9..b4586e9a420e2d 100644
--- a/lldb/include/lldb/Core/Module.h
+++ b/lldb/include/lldb/Core/Module.h
@@ -954,8 +954,9 @@ class Module : public std::enable_shared_from_this<Module>,
     /// \param[in] lang_type
     ///     The language to create lookups for. If eLanguageTypeUnknown is
     ///     passed, creates one LookupInfo for each language plugin currently
-    ///     available in LLDB. If a specific language is provided, creates only
-    ///     a single LookupInfo for that language.
+    ///     available in LLDB, except for full-name lookups that would repeat
+    ///     the lookup of another language. If a specific language is provided,
+    ///     creates only a single LookupInfo for that language.
     ///
     /// \param[in] lookup_name_override
     ///     Manually override the name used for lookup. This parameter is
diff --git a/lldb/include/lldb/Symbol/Symtab.h b/lldb/include/lldb/Symbol/Symtab.h
index 224de9e775859f..ea5e2d8044402b 100644
--- a/lldb/include/lldb/Symbol/Symtab.h
+++ b/lldb/include/lldb/Symbol/Symtab.h
@@ -346,9 +346,9 @@ class Symtab {
                                         SymbolContextList &sc_list);
 
   void RegisterMangledNameEntry(
-      uint32_t value, std::set<const char *> &class_contexts,
-      std::vector<std::pair<NameToIndexMap::Entry, const char *>> &backlog,
-      RichManglingContext &rmc);
+      uint32_t value, const Mangled::FunctionNameParts &parts,
+      std::set<const char *> &class_contexts,
+      std::vector<std::pair<NameToIndexMap::Entry, const char *>> &backlog);
 
   void RegisterBacklogEntry(const NameToIndexMap::Entry &entry,
                             const char *decl_context,
diff --git a/lldb/include/lldb/Target/Language.h b/lldb/include/lldb/Target/Language.h
index c08994cc32e9fd..bd0eb7490346e7 100644
--- a/lldb/include/lldb/Target/Language.h
+++ b/lldb/include/lldb/Target/Language.h
@@ -12,11 +12,14 @@
 
 #include <functional>
 #include <memory>
+#include <optional>
 #include <set>
+#include <string>
 #include <vector>
 
 #include "lldb/Core/FormatEntity.h"
 #include "lldb/Core/Highlighter.h"
+#include "lldb/Core/Mangled.h"
 #include "lldb/Core/PluginInterface.h"
 #include "lldb/DataFormatters/DumpValueObjectOptions.h"
 #include "lldb/DataFormatters/FormatClasses.h"
@@ -167,6 +170,10 @@ class Language : public PluginInterface {
   static Language *FindPlugin(lldb::LanguageType language,
                               llvm::StringRef file_path);
 
+  /// Returns the Language that registered \p scheme with
+  /// Mangled::RegisterManglingScheme(), or a nullptr if none did.
+  static Language *FindPluginForManglingScheme(Mangled::ManglingScheme scheme);
+
   static llvm::Expected<lldb::LanguageType>
   GetExceptionLanguageForLanguage(llvm::StringRef lang_name);
   // return false from callback to stop iterating
@@ -324,6 +331,56 @@ class Language : public PluginInterface {
     return false;
   }
 
+  /// How to demangle a name in DemangleSymbol().
+  struct DemangleOptions {
+    /// Whether to compute the \c DemangledNameInfo too.
+    bool want_info = false;
+  };
+
+  /// A demangled name and, if requested, where its parts begin and end.
+  struct DemangledName {
+    /// Empty if the name couldn't be demangled.
+    std::string name;
+    /// Only computed if DemangleOptions::want_info is true.
+    std::optional<DemangledNameInfo> info;
+  };
+
+  /// Demangle \p mangled, a name mangled with \p scheme, a scheme that this
+  /// language registered with Mangled::RegisterManglingScheme().
+  virtual DemangledName DemangleSymbol(ConstString mangled,
+                                       Mangled::ManglingScheme scheme,
+                                       const DemangleOptions &options) const {
+    return {};
+  }
+
+  /// Parses mangled function names for the symbol table's name indexes.
+  ///
+  /// A symbol table uses one parser for all of its symbols, so a parser can
+  /// reuse state, such as a demangler, between names.
+  class MangledNameParser {
+  public:
+    virtual ~MangledNameParser() = default;
+
+    /// Parse \p mangled, a function name mangled with the scheme that this
+    /// parser was created for.
+    ///
+    /// \return
+    ///   The parts to index the symbol by. If their basename is empty, the
+    ///   symbol is only indexed by its mangled name. std::nullopt if this
+    ///   isn't a function name the parser understands, so that the symbol is
+    ///   indexed by its demangled name instead.
+    virtual std::optional<Mangled::FunctionNameParts>
+    Parse(const Mangled &mangled) = 0;
+  };
+
+  /// Returns a parser for the names mangled with \p scheme, a scheme that this
+  /// language registered, or a nullptr if the symbol table should index them
+  /// by their demangled names.
+  virtual std::unique_ptr<MangledNameParser>
+  CreateMangledNameParser(Mangled::ManglingScheme scheme) const {
+    return nullptr;
+  }
+
   /// An individual data formatter may apply to several types and cross language
   /// boundaries. Each of those languages may want to customize the display of
   /// values of said types by appending proper prefix/suffix information in
diff --git a/lldb/source/Core/Mangled.cpp b/lldb/source/Core/Mangled.cpp
index 06aa1a97309c1b..b5d3e7bb775033 100644
--- a/lldb/source/Core/Mangled.cpp
+++ b/lldb/source/Core/Mangled.cpp
@@ -10,63 +10,182 @@
 
 #include "lldb/Core/DataFileCache.h"
 #include "lldb/Core/DemangledNameInfo.h"
-#include "lldb/Core/RichManglingContext.h"
 #include "lldb/Target/Language.h"
 #include "lldb/Utility/ConstString.h"
 #include "lldb/Utility/DataEncoder.h"
-#include "lldb/Utility/LLDBLog.h"
-#include "lldb/Utility/Log.h"
 #include "lldb/Utility/RegularExpression.h"
 #include "lldb/Utility/Stream.h"
 #include "lldb/lldb-enumerations.h"
 
-#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringRef.h"
-#include "llvm/Demangle/Demangle.h"
 #include "llvm/Support/Compiler.h"
 
+#include <array>
+#include <atomic>
 #include <mutex>
 #include <optional>
 #include <string>
-#include <string_view>
 #include <utility>
+#include <vector>
 
-#include <cstdlib>
-#include <cstring>
 using namespace lldb_private;
 
 #pragma mark Mangled
 
-bool Mangled::IsMangledName(llvm::StringRef name) {
-  return Mangled::GetManglingScheme(name) != Mangled::eManglingSchemeNone;
+namespace {
+/// A mangling scheme that a language plugin registered.
+struct RegisteredManglingScheme {
+  std::vector<std::string> prefixes;
+  /// If set, a name that starts with one of the prefixes must also match.
+  Mangled::ManglingSchemeMatcher matches = nullptr;
+  lldb::LanguageType language = lldb::eLanguageTypeUnknown;
+  /// Schemes are never removed, so that GetManglingScheme() can read them
+  /// without a lock. Unregistered schemes are only marked inactive. No other
+  /// data is published through this flag, so it needs no memory ordering.
+  std::atomic<bool> active = false;
+};
+
+/// The mangling schemes that language plugins registered.
+class ManglingSchemeRegistry {
+public:
+  Mangled::ManglingScheme Register(llvm::ArrayRef<llvm::StringRef> prefixes,
+                                   lldb::LanguageType language,
+                                   Mangled::ManglingSchemeMatcher matches);
+  void Unregister(Mangled::ManglingScheme scheme);
+  lldb::LanguageType GetLanguage(Mangled::ManglingScheme scheme) const;
+  Mangled::ManglingScheme Find(llvm::StringRef name) const;
+
+private:
+  /// Serializes registrations.
+  std::mutex m_mutex;
+  std::array<RegisteredManglingScheme,
+             Mangled::kNumManglingSchemes -
+                 Mangled::eFirstRegisteredManglingScheme>
+      m_schemes;
+  /// The number of initialized entries in m_schemes. Incrementing it publishes
+  /// a new entry to readers.
+  std::atomic<size_t> m_num_schemes = 0;
+};
+} // namespace
+
+static ManglingSchemeRegistry &GetManglingSchemeRegistry() {
+  // NOTE: INTENTIONAL LEAK due to global destructor chain.
+  static ManglingSchemeRegistry *g_registry = new ManglingSchemeRegistry();
+  return *g_registry;
 }
 
-Mangled::ManglingScheme Mangled::GetManglingScheme(llvm::StringRef name) {
-  if (name.empty())
-    return Mangled::eManglingSchemeNone;
+static Mangled::ManglingScheme SchemeForIndex(size_t index) {
+  return static_cast<Mangled::ManglingScheme>(
+      Mangled::eFirstRegisteredManglingScheme + index);
+}
 
-  if (name.starts_with("?"))
-    return Mangled::eManglingSchemeMSVC;
+/// Returns true if a name could start with both one of \p prefixes and a
+/// prefix of one of the active \p schemes.
+[[maybe_unused]] static bool
+OverlapsActiveScheme(llvm::ArrayRef<llvm::StringRef> prefixes,
+                     llvm::ArrayRef<RegisteredManglingScheme> schemes) {
+  for (const RegisteredManglingScheme &scheme : schemes) {
+    if (!scheme.active.load(std::memory_order_relaxed))
+      continue;
+    for (llvm::StringRef prefix : prefixes)
+      for (llvm::StringRef other : scheme.prefixes)
+        if (prefix.starts_with(other) || other.starts_with(prefix))
+          return true;
+  }
+  return false;
+}
+
+Mangled::ManglingScheme
+ManglingSchemeRegistry::Register(llvm::ArrayRef<llvm::StringRef> prefixes,
+                                 lldb::LanguageType language,
+                                 Mangled::ManglingSchemeMatcher matches) {
+  std::lock_guard<std::mutex> guard(m_mutex);
+  const size_t num_schemes = m_num_schemes.load(std::memory_order_relaxed);
+  size_t index = 0;
+  for (; index < num_schemes; ++index) {
+    const RegisteredManglingScheme &scheme = m_schemes[index];
+    if (scheme.language == language && scheme.matches == matches &&
+        llvm::equal(scheme.prefixes, prefixes))
+      break;
+  }
 
-  if (name.starts_with("_R"))
-    return Mangled::eManglingSchemeRustV0;
+  if (index == num_schemes) {
+    assert(index < m_schemes.size() && "too many mangling schemes");
+    if (index >= m_schemes.size())
+      return Mangled::eManglingSchemeNone;
+    assert(!OverlapsActiveScheme(
+               prefixes, llvm::ArrayRef(m_schemes.data(), num_schemes)) &&
+           "mangling scheme prefixes overlap");
+    m_schemes[index].prefixes.assign(prefixes.begin(), prefixes.end());
+    m_schemes[index].matches = matches;
+    m_schemes[index].language = language;
+    m_num_schemes.store(num_schemes + 1, std::memory_order_release);
+  }
+  m_schemes[index].active.store(true, std::memory_order_relaxed);
+  return SchemeForIndex(index);
+}
 
-  if (name.starts_with("_D")) {
-    // A dlang mangled name begins with `_D`, followed by a numeric length. One
-    // known exception is the symbol `_Dmain`.
-    // See `SymbolName` and `LName` in
-    // https://dlang.org/spec/abi.html#name_mangling
-    llvm::StringRef buf = name.drop_front(2);
-    if (!buf.empty() && (llvm::isDigit(buf.front()) || name == "_Dmain"))
-      return Mangled::eManglingSchemeD;
+void ManglingSchemeRegistry::Unregister(Mangled::ManglingScheme scheme) {
+  if (scheme < Mangled::eFirstRegisteredManglingScheme)
+    return;
+  size_t index = scheme - Mangled::eFirstRegisteredManglingScheme;
+  if (index < m_num_schemes.load(std::memory_order_acquire))
+    m_schemes[index].active.store(false, std::memory_order_relaxed);
+}
+
+lldb::LanguageType
+ManglingSchemeRegistry::GetLanguage(Mangled::ManglingScheme scheme) const {
+  if (scheme < Mangled::eFirstRegisteredManglingScheme)
+    return lldb::eLanguageTypeUnknown;
+  size_t index = scheme - Mangled::eFirstRegisteredManglingScheme;
+  if (index >= m_num_schemes.load(std::memory_order_acquire))
+    return lldb::eLanguageTypeUnknown;
+  return m_schemes[index].language;
+}
+
+Mangled::ManglingScheme
+ManglingSchemeRegistry::Find(llvm::StringRef name) const {
+  const size_t num_schemes = m_num_schemes.load(std::memory_order_acquire);
+  for (size_t index = 0; index < num_schemes; ++index) {
+    const RegisteredManglingScheme &scheme = m_schemes[index];
+    if (!scheme.active.load(std::memory_order_relaxed))
+      continue;
+    for (llvm::StringRef prefix : scheme.prefixes) {
+      if (!name.starts_with(prefix))
+        continue;
+      // Prefixes don't overlap, so no other scheme can match the name.
+      if (scheme.matches && !scheme.matches(name))
+        return Mangled::eManglingSchemeNone;
+      return SchemeForIndex(index);
+    }
   }
+  return Mangled::eManglingSchemeNone;
+}
+
+Mangled::ManglingScheme
+Mangled::RegisterManglingScheme(llvm::ArrayRef<llvm::StringRef> prefixes,
+                                lldb::LanguageType language,
+                                ManglingSchemeMatcher matches) {
+  return GetManglingSchemeRegistry().Register(prefixes, language, matches);
+}
+
+void Mangled::UnregisterManglingScheme(ManglingScheme scheme) {
+  GetManglingSchemeRegistry().Unregister(scheme);
+}
 
-  if (name.starts_with("_Z"))
-    return Mangled::eManglingSchemeItanium;
+lldb::LanguageType
+Mangled::GetLanguageForManglingScheme(ManglingScheme scheme) {
+  return GetManglingSchemeRegistry().GetLanguage(scheme);
+}
 
-  // ___Z is a clang extension of block invocations
-  if (name.starts_with("___Z"))
-    return Mangled::eManglingSchemeItanium;
+bool Mangled::IsMangledName(llvm::StringRef name) {
+  return Mangled::GetManglingScheme(name) != Mangled::eManglingSchemeNone;
+}
+
+Mangled::ManglingScheme Mangled::GetManglingScheme(llvm::StringRef name) {
+  if (name.empty())
+    return Mangled::eManglingSchemeNone;
 
   // Swift's older style of mangling used "_T" as a mangling prefix. This can
   // lead to false positives with other symbols that just so happen to start
@@ -88,7 +207,7 @@ Mangled::ManglingScheme Mangled::GetManglingScheme(llvm::StringRef name) {
       name.starts_with("@__swiftmacro_"))
     return Mangled::eManglingSchemeSwift;
 
-  return Mangled::eManglingSchemeNone;
+  return GetManglingSchemeRegistry().Find(name);
 }
 
 Mangled::Mangled(ConstString s) : m_mangled(), m_demangled() {
@@ -136,148 +255,6 @@ void Mangled::SetValue(ConstString name) {
   }
 }
 
-// Local helpers for different demangling implementations.
-static char *GetMSVCDemangledStr(llvm::StringRef M) {
-  char *demangled_cstr = llvm::microsoftDemangle(
-      M, nullptr, nullptr,
-      llvm::MSDemangleFlags(
-          llvm::MSDF_NoAccessSpecifier | llvm::MSDF_NoCallingConvention |
-          llvm::MSDF_NoMemberType | llvm::MSDF_NoVariableType));
-
-  if (Log *log = GetLog(LLDBLog::Demangle)) {
-    if (demangled_cstr && demangled_cstr[0])
-      LLDB_LOGF(log, "demangled msvc: %s -> \"%s\"", M.data(), demangled_cstr);
-    else
-      LLDB_LOGF(log, "demangled msvc: %s -> error", M.data());
-  }
-
-  return demangled_cstr;
-}
-
-static std::pair<char *, DemangledNameInfo>
-GetItaniumDemangledStr(const char *M) {
-  char *demangled_cstr = nullptr;
-
-  DemangledNameInfo info;
-  llvm::ItaniumPartialDemangler ipd;
-  bool err = ipd.partialDemangle(M);
-  if (!err) {
-    // Default buffer and size (OutputBuffer will realloc in case it's too
-    // small).
-    size_t demangled_size = 80;
-    demangled_cstr = static_cast<char *>(std::malloc(80));
-
-    TrackingOutputBuffer OB(demangled_cstr, demangled_size);
-    demangled_cstr = ipd.finishDemangle(&OB);
-    info = std::move(OB.NameInfo);
-
-    assert(demangled_cstr &&
-           "finishDemangle must always succeed if partialDemangle ...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/232929


More information about the lldb-commits mailing list