[Lldb-commits] [lldb] 64b5bc8 - [lldb][Format] Add function.suffix frame-format variable (#137763)
via lldb-commits
lldb-commits at lists.llvm.org
Tue Apr 29 02:02:51 PDT 2025
Author: Michael Buch
Date: 2025-04-29T10:02:44+01:00
New Revision: 64b5bc876aef6db89c38cf5dc76eebec38187234
URL: https://github.com/llvm/llvm-project/commit/64b5bc876aef6db89c38cf5dc76eebec38187234
DIFF: https://github.com/llvm/llvm-project/commit/64b5bc876aef6db89c38cf5dc76eebec38187234.diff
LOG: [lldb][Format] Add function.suffix frame-format variable (#137763)
This patch adds another frame-format variable (currently only
implemented in the CPlusPlus language plugin) that represents the
"suffix" of a function. The name is derived from the `DotSuffix` node of
LLVM's Itanium demangler.
For a function name such as `int foo() (.cold)`, the suffix would be
`(.cold)`.
Added:
lldb/test/Shell/Settings/TestFrameFormatFunctionSuffix.test
Modified:
lldb/docs/use/formatting.rst
lldb/include/lldb/Core/FormatEntity.h
lldb/source/Core/FormatEntity.cpp
lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
lldb/source/Plugins/Language/CPlusPlus/LanguageCPlusPlusProperties.td
Removed:
################################################################################
diff --git a/lldb/docs/use/formatting.rst b/lldb/docs/use/formatting.rst
index a21165a3ecae3..61f51812d2ea9 100644
--- a/lldb/docs/use/formatting.rst
+++ b/lldb/docs/use/formatting.rst
@@ -106,6 +106,8 @@ A complete list of currently supported format string variables is listed below:
| ``function.return-right`` | The return type to the right of the demangled function name of the current function. This depends on the frame's language. In ``void ns::foo(int)`` there is no ``function.return-right`` so this would correspond to an empty string. However, in some cases, particularly for functions |
| | returning function pointers, part of the return type is to the right of the function name. E.g., for ``void (*ns::func(float))(int)`` the ``function.return-left`` would be ``void (*`` and the ``function.return-right`` would be ``)(int)``. |
+---------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| ``function.suffix`` | Any suffix added to the demangled function name of the current function. This depends on the frame's language. E.g., for C++ the suffix for ``void ns::foo(int) (.cold)`` is '(.cold). |
++---------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``function.mangled-name`` | The mangled name of the current function or symbol. |
+---------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``function.pc-offset`` | The program counter offset within the current function or symbol |
@@ -329,6 +331,7 @@ The function names displayed in backtraces/``frame info``/``thread info`` are th
- ``${function.formatted-arguments}``
- ``${function.qualifiers}``
- ``${function.return-right}``
+- ``${function.suffix}``
Each language plugin decides how to handle these variables. For C++, LLDB uses these variables to dictate how function names are formatted. This can be customized using the ``plugin.cplusplus.display.function-name-format`` LLDB setting.
@@ -336,19 +339,19 @@ E.g., the following setting would reconstruct the entire function name (and is L
::
- (lldb) settings set plugin.cplusplus.dislpay.function-name-format "${function.return-left}${function.scope}${function.basename}${function.template-arguments}${function.formatted-arguments}${function.qualifiers}${function.return-right}"
+ (lldb) settings set plugin.cplusplus.dislpay.function-name-format "${function.return-left}${function.scope}${function.basename}${function.template-arguments}${function.formatted-arguments}${function.qualifiers}${function.return-right}${function.suffix}"
-If a user wanted to omit the return type and template arguments of C++ function names one could do:
+If a user wanted to only print the name and arguments of a C++ function one could do:
::
- (lldb) settings set plugin.cplusplus.dislpay.function-name-format "${function.scope}${function.basename}${function.formatted-arguments}${function.qualifiers}"
+ (lldb) settings set plugin.cplusplus.dislpay.function-name-format "${function.scope}${function.basename}${function.formatted-arguments}"
Then the following would highlight just the basename in green:
::
- (lldb) settings set plugin.cplusplus.dislpay.function-name-format "${function.scope}${ansi.fg.yellow}${function.basename}${ansi.normal}${function.formatted-arguments}${function.qualifiers}"
+ (lldb) settings set plugin.cplusplus.dislpay.function-name-format "${function.scope}${ansi.fg.yellow}${function.basename}${ansi.normal}${function.formatted-arguments}"
The ``${function.name-with-args}`` by default asks the language plugin whether it supports a language-specific ``function-name-format`` (e.g., the ``plugin.cplusplus.display.function-name-format`` for C++), and if it does, uses it. Otherwise it will display the demangled function name.
diff --git a/lldb/include/lldb/Core/FormatEntity.h b/lldb/include/lldb/Core/FormatEntity.h
index e62c82d080d5f..97065afe19bfe 100644
--- a/lldb/include/lldb/Core/FormatEntity.h
+++ b/lldb/include/lldb/Core/FormatEntity.h
@@ -95,6 +95,7 @@ struct Entry {
FunctionReturnLeft,
FunctionReturnRight,
FunctionQualifiers,
+ FunctionSuffix,
FunctionAddrOffset,
FunctionAddrOffsetConcrete,
FunctionLineOffset,
diff --git a/lldb/source/Core/FormatEntity.cpp b/lldb/source/Core/FormatEntity.cpp
index 6cdfcfedf8be5..468203ac73a42 100644
--- a/lldb/source/Core/FormatEntity.cpp
+++ b/lldb/source/Core/FormatEntity.cpp
@@ -130,6 +130,7 @@ constexpr Definition g_function_child_entries[] = {
Definition("return-left", EntryType::FunctionReturnLeft),
Definition("return-right", EntryType::FunctionReturnRight),
Definition("qualifiers", EntryType::FunctionQualifiers),
+ Definition("suffix", EntryType::FunctionSuffix),
};
constexpr Definition g_line_child_entries[] = {
@@ -368,6 +369,7 @@ const char *FormatEntity::Entry::TypeToCString(Type t) {
ENUM_TO_CSTR(FunctionReturnLeft);
ENUM_TO_CSTR(FunctionReturnRight);
ENUM_TO_CSTR(FunctionQualifiers);
+ ENUM_TO_CSTR(FunctionSuffix);
ENUM_TO_CSTR(FunctionAddrOffset);
ENUM_TO_CSTR(FunctionAddrOffsetConcrete);
ENUM_TO_CSTR(FunctionLineOffset);
@@ -1808,6 +1810,7 @@ bool FormatEntity::Format(const Entry &entry, Stream &s,
case Entry::Type::FunctionFormattedArguments:
case Entry::Type::FunctionReturnRight:
case Entry::Type::FunctionReturnLeft:
+ case Entry::Type::FunctionSuffix:
case Entry::Type::FunctionQualifiers: {
if (!sc->function)
return false;
diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index 283e867d53bb7..6491fb761de52 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -381,6 +381,30 @@ GetDemangledScope(const SymbolContext &sc) {
return demangled_name.slice(info->ScopeRange.first, info->ScopeRange.second);
}
+/// Handles anything printed after the FunctionEncoding ItaniumDemangle
+/// node. Most notably the DotSUffix node.
+static std::optional<llvm::StringRef>
+GetDemangledFunctionSuffix(const SymbolContext &sc) {
+ Mangled mangled = sc.GetPossiblyInlinedFunctionName();
+ if (!mangled)
+ return std::nullopt;
+
+ auto demangled_name = mangled.GetDemangledName().GetStringRef();
+ if (demangled_name.empty())
+ return std::nullopt;
+
+ const std::optional<DemangledNameInfo> &info = mangled.GetDemangledInfo();
+ if (!info)
+ return std::nullopt;
+
+ // Function without a basename is nonsense.
+ if (!info->hasBasename())
+ return std::nullopt;
+
+ return demangled_name.slice(info->QualifiersRange.second,
+ llvm::StringRef::npos);
+}
+
bool CPlusPlusLanguage::CxxMethodName::TrySimplifiedParse() {
// This method tries to parse simple method definitions which are presumably
// most comman in user programs. Definitions that can be parsed by this
@@ -1966,6 +1990,15 @@ bool CPlusPlusLanguage::HandleFrameFormatVariable(
return true;
}
+ case FormatEntity::Entry::Type::FunctionSuffix: {
+ std::optional<llvm::StringRef> suffix = GetDemangledFunctionSuffix(sc);
+ if (!suffix)
+ return false;
+
+ s << *suffix;
+
+ return true;
+ }
default:
return false;
}
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LanguageCPlusPlusProperties.td b/lldb/source/Plugins/Language/CPlusPlus/LanguageCPlusPlusProperties.td
index 348de256b154a..4d74a040f4de4 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LanguageCPlusPlusProperties.td
+++ b/lldb/source/Plugins/Language/CPlusPlus/LanguageCPlusPlusProperties.td
@@ -3,6 +3,6 @@ include "../../../../include/lldb/Core/PropertiesBase.td"
let Definition = "language_cplusplus" in {
def FunctionNameFormat: Property<"function-name-format", "FormatEntity">,
Global,
- DefaultStringValue<"${function.return-left}${function.scope}${ansi.fg.yellow}${function.basename}${ansi.normal}${function.template-arguments}${function.formatted-arguments}${function.return-right}${function.qualifiers}">,
+ DefaultStringValue<"${function.return-left}${function.scope}${ansi.fg.yellow}${function.basename}${ansi.normal}${function.template-arguments}${function.formatted-arguments}${function.return-right}${function.qualifiers}${function.suffix}">,
Desc<"C++ specific frame format string to use when displaying stack frame information for threads.">;
}
diff --git a/lldb/test/Shell/Settings/TestFrameFormatFunctionSuffix.test b/lldb/test/Shell/Settings/TestFrameFormatFunctionSuffix.test
new file mode 100644
index 0000000000000..ce7fa22b00b5a
--- /dev/null
+++ b/lldb/test/Shell/Settings/TestFrameFormatFunctionSuffix.test
@@ -0,0 +1,23 @@
+# XFAIL: target-windows
+
+# Test the ${function.suffix} frame-format variable.
+
+# RUN: split-file %s %t
+# RUN: %clang_host -g -gdwarf %t/main.cpp -o %t.out
+# RUN: %lldb -x -b -s %t/commands.input %t.out -o exit 2>&1 \
+# RUN: | FileCheck %s
+
+#--- main.cpp
+void bar() asm("_Z3barv.cold");
+void bar() {}
+
+int main() { bar(); }
+
+#--- commands.input
+settings set -f frame-format "custom-frame '${function.suffix}'\n"
+break set -n "_Z3barv.cold"
+
+run
+bt
+
+# CHECK: custom-frame ' (.cold)'
More information about the lldb-commits
mailing list