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 _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits