[Lldb-commits] [lldb] b8997c0 - [Demangling] Refactor Demangler range tracking (#140762)
via lldb-commits
lldb-commits at lists.llvm.org
Wed May 28 05:53:05 PDT 2025
Author: Charles Zablit
Date: 2025-05-28T13:53:02+01:00
New Revision: b8997c07d9783bbf81bf144b5982d43ba804f5ac
URL: https://github.com/llvm/llvm-project/commit/b8997c07d9783bbf81bf144b5982d43ba804f5ac
DIFF: https://github.com/llvm/llvm-project/commit/b8997c07d9783bbf81bf144b5982d43ba804f5ac.diff
LOG: [Demangling] Refactor Demangler range tracking (#140762)
This PR is a subset of the commits made in
https://github.com/swiftlang/llvm-project/pull/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).
Added:
lldb/test/Shell/Settings/TestFrameFormatFunctionPrefix.test
Modified:
lldb/docs/use/formatting.rst
lldb/include/lldb/Core/DemangledNameInfo.h
lldb/include/lldb/Core/FormatEntity.h
lldb/source/Core/FormatEntity.cpp
lldb/source/Core/Mangled.cpp
lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
Removed:
################################################################################
diff --git a/lldb/docs/use/formatting.rst b/lldb/docs/use/formatting.rst
index 61f51812d2ea9..e71b08780eb3d 100644
--- a/lldb/docs/use/formatting.rst
+++ b/lldb/docs/use/formatting.rst
@@ -91,7 +91,9 @@ A complete list of currently supported format string variables is listed below:
+---------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``function.basename`` | The basename of the current function depending on the frame's language. E.g., for C++ the basename for ``void ns::foo<float>::bar<int>(int) const`` is ``bar``. |
+---------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
-| ``function.scope`` | The scope qualifiers of the current function depending on the frame's language. E.g., for C++ the scope for ``void ns::foo<float>::bar<int>(int) const`` is ``ns::foo<float>``. |
+| ``function.prefix`` | Any prefix added to the demangled function name of the current function. This depends on the frame's language. E.g., for C++ the prefix will always be empty. |
++---------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| ``function.scope`` | The scope qualifiers of the current function depending on the frame's language. E.g., for C++ the scope for ``void ns::foo<float>::bar<int>(int) const`` is ``ns::foo<float>``. |
+---------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``function.template-arguments`` | The template arguments of the current function depending on the frame's language. E.g., for C++ the template arguments for ``void ns::foo<float>::bar<int>(int) const`` are ``<float>``. |
+---------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
@@ -325,6 +327,7 @@ _____________________
The function names displayed in backtraces/``frame info``/``thread info`` are the demangled names of functions. On some platforms (like ones using Itanium the mangling scheme), LLDB supports decomposing these names into fine-grained components. These are currently:
- ``${function.return-left}``
+- ``${function.prefix}``
- ``${function.scope}``
- ``${function.basename}``
- ``${function.template-arguments}``
diff --git a/lldb/include/lldb/Core/DemangledNameInfo.h b/lldb/include/lldb/Core/DemangledNameInfo.h
index 11d3bb58871b8..ab9bb3e211b66 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,6 +59,16 @@ 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 &&
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..0027bfaeda4f7 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_view(OB).size();
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 b178e06a975cd..7485577ae67e0 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/test/Shell/Settings/TestFrameFormatFunctionPrefix.test b/lldb/test/Shell/Settings/TestFrameFormatFunctionPrefix.test
new file mode 100644
index 0000000000000..5bf1990d24c32
--- /dev/null
+++ b/lldb/test/Shell/Settings/TestFrameFormatFunctionPrefix.test
@@ -0,0 +1,24 @@
+# Check that we have an appropriate fallback for ${function.prefix} in languages that
+# don't implement this frame format variable (in this case Objective-C).
+#
+# RUN: split-file %s %t
+# RUN: %clang_host -g -gdwarf %t/main.m -o %t.objc.out
+# RUN: %lldb -x -b -s %t/commands.input %t.objc.out -o exit 2>&1 \
+# RUN: | FileCheck %s
+
+#--- main.m
+
+int func() {}
+int bar() { func(); }
+
+int main() { return bar(); }
+
+#--- commands.input
+settings set -f frame-format "custom-frame '${function.prefix}'\n"
+break set -n bar
+
+run
+bt
+
+# CHECK: bt
+# CHECK-NOT: custom-frame
More information about the lldb-commits
mailing list