Skip to content

[Demangling] Refactor Demangler range tracking #140762

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

charles-zablit
Copy link
Contributor

This PR is a subset of the commits made in swiftlang#10710.

The most notable change is the addition of PrefixRange and SuffixRange which are a catch-all to track anything after or before a function's demangled name. In the case of Swift, this allows to add support for name highlighting without having to track the range of the scope and specifiers of a function (this will come in another PR).

@llvmbot
Copy link
Member

llvmbot commented May 20, 2025

@llvm/pr-subscribers-lldb

Author: Charles Zablit (charles-zablit)

Changes

This PR is a subset of the commits made in swiftlang#10710.

The most notable change is the addition of PrefixRange and SuffixRange which are a catch-all to track anything after or before a function's demangled name. In the case of Swift, this allows to add support for name highlighting without having to track the range of the scope and specifiers of a function (this will come in another PR).


Full diff: https://github.com/llvm/llvm-project/pull/140762.diff

7 Files Affected:

  • (modified) lldb/include/lldb/Core/DemangledNameInfo.h (+17-1)
  • (modified) lldb/include/lldb/Core/FormatEntity.h (+1)
  • (modified) lldb/source/Core/FormatEntity.cpp (+3)
  • (modified) lldb/source/Core/Mangled.cpp (+2)
  • (modified) lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp (+2-2)
  • (modified) lldb/unittests/Core/CMakeLists.txt (+1-1)
  • (renamed) lldb/unittests/Core/ItaniumMangledTest.cpp (+7-6)
diff --git a/lldb/include/lldb/Core/DemangledNameInfo.h b/lldb/include/lldb/Core/DemangledNameInfo.h
index 11d3bb58871b8..76cf8908fcbe6 100644
--- a/lldb/include/lldb/Core/DemangledNameInfo.h
+++ b/lldb/include/lldb/Core/DemangledNameInfo.h
@@ -39,7 +39,7 @@ struct DemangledNameInfo {
   /// \endcode
   std::pair<size_t, size_t> ScopeRange;
 
-  /// Indicates the [start, end) of the function argument lits.
+  /// Indicates the [start, end) of the function argument list.
   /// E.g.,
   /// \code{.cpp}
   ///    int (*getFunc<float>(float, double))(int, int)
@@ -59,11 +59,27 @@ struct DemangledNameInfo {
   /// \endcode
   std::pair<size_t, size_t> QualifiersRange;
 
+  /// Indicates the [start, end) of the function's prefix. This is a
+  /// catch-all range for anything that is not tracked by the rest of
+  /// the pairs.
+  std::pair<size_t, size_t> PrefixRange;
+
+  /// Indicates the [start, end) of the function's suffix. This is a
+  /// catch-all range for anything that is not tracked by the rest of
+  /// the pairs.
+  std::pair<size_t, size_t> SuffixRange;
+
   /// Returns \c true if this object holds a valid basename range.
   bool hasBasename() const {
     return BasenameRange.second > BasenameRange.first &&
            BasenameRange.second > 0;
   }
+
+  /// Returns \c true if this object holds a valid arguments range.
+  bool hasArguments() const {
+    return ArgumentsRange.second > ArgumentsRange.first &&
+           ArgumentsRange.second > 0;
+  }
 };
 
 /// An OutputBuffer which keeps a record of where certain parts of a
diff --git a/lldb/include/lldb/Core/FormatEntity.h b/lldb/include/lldb/Core/FormatEntity.h
index 6acf6fbe43239..1aed3c6ff9e9d 100644
--- a/lldb/include/lldb/Core/FormatEntity.h
+++ b/lldb/include/lldb/Core/FormatEntity.h
@@ -88,6 +88,7 @@ struct Entry {
     FunctionNameWithArgs,
     FunctionNameNoArgs,
     FunctionMangledName,
+    FunctionPrefix,
     FunctionScope,
     FunctionBasename,
     FunctionTemplateArguments,
diff --git a/lldb/source/Core/FormatEntity.cpp b/lldb/source/Core/FormatEntity.cpp
index 4f2d39873c7fb..4dcfa43a7bb04 100644
--- a/lldb/source/Core/FormatEntity.cpp
+++ b/lldb/source/Core/FormatEntity.cpp
@@ -124,6 +124,7 @@ constexpr Definition g_function_child_entries[] = {
     Definition("initial-function", EntryType::FunctionInitial),
     Definition("changed", EntryType::FunctionChanged),
     Definition("is-optimized", EntryType::FunctionIsOptimized),
+    Definition("prefix", EntryType::FunctionPrefix),
     Definition("scope", EntryType::FunctionScope),
     Definition("basename", EntryType::FunctionBasename),
     Definition("template-arguments", EntryType::FunctionTemplateArguments),
@@ -385,6 +386,7 @@ const char *FormatEntity::Entry::TypeToCString(Type t) {
     ENUM_TO_CSTR(FunctionNameWithArgs);
     ENUM_TO_CSTR(FunctionNameNoArgs);
     ENUM_TO_CSTR(FunctionMangledName);
+    ENUM_TO_CSTR(FunctionPrefix);
     ENUM_TO_CSTR(FunctionScope);
     ENUM_TO_CSTR(FunctionBasename);
     ENUM_TO_CSTR(FunctionTemplateArguments);
@@ -1835,6 +1837,7 @@ bool FormatEntity::Format(const Entry &entry, Stream &s,
     return true;
   }
 
+  case Entry::Type::FunctionPrefix:
   case Entry::Type::FunctionScope:
   case Entry::Type::FunctionBasename:
   case Entry::Type::FunctionTemplateArguments:
diff --git a/lldb/source/Core/Mangled.cpp b/lldb/source/Core/Mangled.cpp
index ce4db4e0daa8b..e6f7d198d7316 100644
--- a/lldb/source/Core/Mangled.cpp
+++ b/lldb/source/Core/Mangled.cpp
@@ -172,6 +172,8 @@ GetItaniumDemangledStr(const char *M) {
 
     TrackingOutputBuffer OB(demangled_cstr, demangled_size);
     demangled_cstr = ipd.finishDemangle(&OB);
+    OB.NameInfo.SuffixRange.first = OB.NameInfo.QualifiersRange.second;
+    OB.NameInfo.SuffixRange.second = std::string(demangled_cstr).length();
     info = std::move(OB.NameInfo);
 
     assert(demangled_cstr &&
diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index 542f13bef23e7..f45b4fb816b3b 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -401,8 +401,8 @@ GetDemangledFunctionSuffix(const SymbolContext &sc) {
   if (!info->hasBasename())
     return std::nullopt;
 
-  return demangled_name.slice(info->QualifiersRange.second,
-                              llvm::StringRef::npos);
+  return demangled_name.slice(info->SuffixRange.first,
+                              info->SuffixRange.second);
 }
 
 static bool PrintDemangledArgumentList(Stream &s, const SymbolContext &sc) {
diff --git a/lldb/unittests/Core/CMakeLists.txt b/lldb/unittests/Core/CMakeLists.txt
index 97268b3dbf8f8..234eb43b95257 100644
--- a/lldb/unittests/Core/CMakeLists.txt
+++ b/lldb/unittests/Core/CMakeLists.txt
@@ -6,7 +6,7 @@ add_lldb_unittest(LLDBCoreTests
   DumpDataExtractorTest.cpp
   DumpRegisterInfoTest.cpp
   FormatEntityTest.cpp
-  MangledTest.cpp
+  ItaniumMangledTest.cpp
   ModuleSpecTest.cpp
   PluginManagerTest.cpp
   ProgressReportTest.cpp
diff --git a/lldb/unittests/Core/MangledTest.cpp b/lldb/unittests/Core/ItaniumMangledTest.cpp
similarity index 98%
rename from lldb/unittests/Core/MangledTest.cpp
rename to lldb/unittests/Core/ItaniumMangledTest.cpp
index 44651eb94c23b..fef2b14af0948 100644
--- a/lldb/unittests/Core/MangledTest.cpp
+++ b/lldb/unittests/Core/ItaniumMangledTest.cpp
@@ -1,4 +1,4 @@
-//===-- MangledTest.cpp ---------------------------------------------------===//
+//===-- ItaniumMangledTest.cpp --------------------------------------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -401,7 +401,7 @@ TEST(MangledTest, DemangledNameInfo_SetValue) {
   EXPECT_FALSE(mangled.GetDemangledInfo()->hasBasename());
 }
 
-struct DemanglingPartsTestCase {
+struct ItaniumDemanglingPartsTestCase {
   const char *mangled;
   DemangledNameInfo expected_info;
   std::string_view basename;
@@ -410,7 +410,7 @@ struct DemanglingPartsTestCase {
   bool valid_basename = true;
 };
 
-DemanglingPartsTestCase g_demangling_parts_test_cases[] = {
+ItaniumDemanglingPartsTestCase g_demangling_itanium_parts_test_cases[] = {
     // clang-format off
    { "_ZNVKO3BarIN2ns3QuxIiEEE1CIPFi3FooIS_IiES6_EEE6methodIS6_EENS5_IT_SC_E5InnerIiEESD_SD_",
      { /*.BasenameRange=*/{92, 98}, /*.ScopeRange=*/{36, 92}, /*.ArgumentsRange=*/{ 108, 158 },
@@ -555,7 +555,7 @@ DemanglingPartsTestCase g_demangling_parts_test_cases[] = {
 };
 
 struct DemanglingPartsTestFixture
-    : public ::testing::TestWithParam<DemanglingPartsTestCase> {};
+    : public ::testing::TestWithParam<ItaniumDemanglingPartsTestCase> {};
 
 namespace {
 class TestAllocator {
@@ -608,5 +608,6 @@ TEST_P(DemanglingPartsTestFixture, DemanglingParts) {
   std::free(OB.getBuffer());
 }
 
-INSTANTIATE_TEST_SUITE_P(DemanglingPartsTests, DemanglingPartsTestFixture,
-                         ::testing::ValuesIn(g_demangling_parts_test_cases));
+INSTANTIATE_TEST_SUITE_P(
+    DemanglingPartsTests, DemanglingPartsTestFixture,
+    ::testing::ValuesIn(g_demangling_itanium_parts_test_cases));

@JDevlieghere JDevlieghere requested a review from Michael137 May 20, 2025 23:19
/// Returns \c true if this object holds a valid basename range.
bool hasBasename() const {
return BasenameRange.second > BasenameRange.first &&
BasenameRange.second > 0;
return BasenameRange.second > BasenameRange.first;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you elaborate why this was needed?

}

/// Returns \c true if this object holds a valid arguments range.
bool hasArguments() const {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems unused?

@@ -88,6 +88,7 @@ struct Entry {
FunctionNameWithArgs,
FunctionNameNoArgs,
FunctionMangledName,
FunctionPrefix,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we add a new variable here we will need to update the documentation under lldb/docs/use/formatting.rst

@@ -6,7 +6,7 @@ add_lldb_unittest(LLDBCoreTests
DumpDataExtractorTest.cpp
DumpRegisterInfoTest.cpp
FormatEntityTest.cpp
MangledTest.cpp
ItaniumMangledTest.cpp
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't mind renaming the file but there are already swift mangling tests in this file, so ItaniumMangled isn't quite correct. What's the motivation for the rename?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants