[libcxxabi] [lldb] [llvm] [lldb] Add option to highlight function names in backtraces (PR #131836)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 8 06:27:44 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-lldb
@llvm/pr-subscribers-libcxxabi
Author: Michael Buch (Michael137)
<details>
<summary>Changes</summary>
This patch adds a new `frame-format` variable to allow highlighting function basenames when formatting frame names in LLDB ([see this RFC](https://discourse.llvm.org/t/rfc-lldb-highlighting-function-names-in-lldb-backtraces/85309)). This is done by tracking information about components of a demangled function name and plumbing that from the demangler through to LLDB. We expose this with a new `frame-format` variable to `${function.name-with-args}` (and can be easily extended to the other types of `${function.XXX}` variables. The new specifier looks as follows:
```
${function.name-with-args:%highlight_basename(ansi.fg.cyan)}
```
This
The plan is to eventually, after living on the option for some time, add it to the default `frame-format` setting.
Example highlighted backtrace:
<img width="1512" alt="Screenshot 2025-03-19 at 14 39 30" src="https://github.com/user-attachments/assets/b24f9c9f-029d-4a64-ad12-db2ad652ed71" />
**Changes**
* Commit 1 (separately reviewed in https://github.com/llvm/llvm-project/pull/133249): required demangler interface changes to allow tracking of basename locations
* Commit 2: implements the `TrackingOutputBuffer`
* Commit 3: add version of `GetDemangledName` that will force re-demangling. This is required because LLDB will `SetDemangledName` without going through the demangler. So we need a way to force demangling to set the `m_demangled_info` member when we need it
* Commit 4: changes `GetDemangledName` to use the `TrackingOutputBuffer` and populate the `m_demangled_info` member
* Commit 5: implements the new `frame-format` specifier. This is what implements the actual highlighting
---
Patch is 67.09 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/131836.diff
21 Files Affected:
- (modified) libcxxabi/src/demangle/ItaniumDemangle.h (+36-28)
- (modified) libcxxabi/src/demangle/Utility.h (+7)
- (added) lldb/include/lldb/Core/DemangledNameInfo.h (+151)
- (modified) lldb/include/lldb/Core/FormatEntity.h (+28)
- (modified) lldb/include/lldb/Core/Mangled.h (+23-3)
- (modified) lldb/include/lldb/Symbol/Function.h (+4)
- (modified) lldb/include/lldb/Target/Language.h (+5-4)
- (modified) lldb/source/Core/CMakeLists.txt (+1)
- (added) lldb/source/Core/DemangledNameInfo.cpp (+213)
- (modified) lldb/source/Core/FormatEntity.cpp (+74-3)
- (modified) lldb/source/Core/Mangled.cpp (+42-10)
- (modified) lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp (+75-9)
- (modified) lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h (+5-4)
- (modified) lldb/source/Symbol/Function.cpp (+4)
- (modified) lldb/source/Target/Language.cpp (+4-4)
- (added) lldb/test/Shell/Settings/TestFrameFormatHighlight.test (+77)
- (modified) lldb/unittests/Core/MangledTest.cpp (+214)
- (modified) llvm/include/llvm/Demangle/Demangle.h (+7)
- (modified) llvm/include/llvm/Demangle/ItaniumDemangle.h (+36-28)
- (modified) llvm/include/llvm/Demangle/Utility.h (+7)
- (modified) llvm/lib/Demangle/ItaniumDemangle.cpp (+14-3)
``````````diff
diff --git a/libcxxabi/src/demangle/ItaniumDemangle.h b/libcxxabi/src/demangle/ItaniumDemangle.h
index 3df41b5f4d7d0..89a24def830f2 100644
--- a/libcxxabi/src/demangle/ItaniumDemangle.h
+++ b/libcxxabi/src/demangle/ItaniumDemangle.h
@@ -281,9 +281,9 @@ class Node {
}
void print(OutputBuffer &OB) const {
- printLeft(OB);
+ OB.printLeft(*this);
if (RHSComponentCache != Cache::No)
- printRight(OB);
+ OB.printRight(*this);
}
// Print the "left" side of this Node into OutputBuffer.
@@ -458,11 +458,11 @@ class QualType final : public Node {
}
void printLeft(OutputBuffer &OB) const override {
- Child->printLeft(OB);
+ OB.printLeft(*Child);
printQuals(OB);
}
- void printRight(OutputBuffer &OB) const override { Child->printRight(OB); }
+ void printRight(OutputBuffer &OB) const override { OB.printRight(*Child); }
};
class ConversionOperatorType final : public Node {
@@ -491,7 +491,7 @@ class PostfixQualifiedType final : public Node {
template<typename Fn> void match(Fn F) const { F(Ty, Postfix); }
void printLeft(OutputBuffer &OB) const override {
- Ty->printLeft(OB);
+ OB.printLeft(*Ty);
OB += Postfix;
}
};
@@ -577,7 +577,7 @@ struct AbiTagAttr : Node {
std::string_view getBaseName() const override { return Base->getBaseName(); }
void printLeft(OutputBuffer &OB) const override {
- Base->printLeft(OB);
+ OB.printLeft(*Base);
OB += "[abi:";
OB += Tag;
OB += "]";
@@ -644,7 +644,7 @@ class PointerType final : public Node {
// We rewrite objc_object<SomeProtocol>* into id<SomeProtocol>.
if (Pointee->getKind() != KObjCProtoName ||
!static_cast<const ObjCProtoName *>(Pointee)->isObjCObject()) {
- Pointee->printLeft(OB);
+ OB.printLeft(*Pointee);
if (Pointee->hasArray(OB))
OB += " ";
if (Pointee->hasArray(OB) || Pointee->hasFunction(OB))
@@ -663,7 +663,7 @@ class PointerType final : public Node {
!static_cast<const ObjCProtoName *>(Pointee)->isObjCObject()) {
if (Pointee->hasArray(OB) || Pointee->hasFunction(OB))
OB += ")";
- Pointee->printRight(OB);
+ OB.printRight(*Pointee);
}
}
};
@@ -729,7 +729,7 @@ class ReferenceType : public Node {
std::pair<ReferenceKind, const Node *> Collapsed = collapse(OB);
if (!Collapsed.second)
return;
- Collapsed.second->printLeft(OB);
+ OB.printLeft(*Collapsed.second);
if (Collapsed.second->hasArray(OB))
OB += " ";
if (Collapsed.second->hasArray(OB) || Collapsed.second->hasFunction(OB))
@@ -746,7 +746,7 @@ class ReferenceType : public Node {
return;
if (Collapsed.second->hasArray(OB) || Collapsed.second->hasFunction(OB))
OB += ")";
- Collapsed.second->printRight(OB);
+ OB.printRight(*Collapsed.second);
}
};
@@ -766,7 +766,7 @@ class PointerToMemberType final : public Node {
}
void printLeft(OutputBuffer &OB) const override {
- MemberType->printLeft(OB);
+ OB.printLeft(*MemberType);
if (MemberType->hasArray(OB) || MemberType->hasFunction(OB))
OB += "(";
else
@@ -778,7 +778,7 @@ class PointerToMemberType final : public Node {
void printRight(OutputBuffer &OB) const override {
if (MemberType->hasArray(OB) || MemberType->hasFunction(OB))
OB += ")";
- MemberType->printRight(OB);
+ OB.printRight(*MemberType);
}
};
@@ -798,7 +798,7 @@ class ArrayType final : public Node {
bool hasRHSComponentSlow(OutputBuffer &) const override { return true; }
bool hasArraySlow(OutputBuffer &) const override { return true; }
- void printLeft(OutputBuffer &OB) const override { Base->printLeft(OB); }
+ void printLeft(OutputBuffer &OB) const override { OB.printLeft(*Base); }
void printRight(OutputBuffer &OB) const override {
if (OB.back() != ']')
@@ -807,7 +807,7 @@ class ArrayType final : public Node {
if (Dimension)
Dimension->print(OB);
OB += "]";
- Base->printRight(OB);
+ OB.printRight(*Base);
}
bool printInitListAsType(OutputBuffer &OB,
@@ -851,7 +851,7 @@ class FunctionType final : public Node {
// by printing out the return types's left, then print our parameters, then
// finally print right of the return type.
void printLeft(OutputBuffer &OB) const override {
- Ret->printLeft(OB);
+ OB.printLeft(*Ret);
OB += " ";
}
@@ -859,7 +859,7 @@ class FunctionType final : public Node {
OB.printOpen();
Params.printWithComma(OB);
OB.printClose();
- Ret->printRight(OB);
+ OB.printRight(*Ret);
if (CVQuals & QualConst)
OB += " const";
@@ -964,6 +964,8 @@ class FunctionEncoding final : public Node {
FunctionRefQual getRefQual() const { return RefQual; }
NodeArray getParams() const { return Params; }
const Node *getReturnType() const { return Ret; }
+ const Node *getAttrs() const { return Attrs; }
+ const Node *getRequires() const { return Requires; }
bool hasRHSComponentSlow(OutputBuffer &) const override { return true; }
bool hasFunctionSlow(OutputBuffer &) const override { return true; }
@@ -972,10 +974,11 @@ class FunctionEncoding final : public Node {
void printLeft(OutputBuffer &OB) const override {
if (Ret) {
- Ret->printLeft(OB);
+ OB.printLeft(*Ret);
if (!Ret->hasRHSComponent(OB))
OB += " ";
}
+
Name->print(OB);
}
@@ -983,8 +986,9 @@ class FunctionEncoding final : public Node {
OB.printOpen();
Params.printWithComma(OB);
OB.printClose();
+
if (Ret)
- Ret->printRight(OB);
+ OB.printRight(*Ret);
if (CVQuals & QualConst)
OB += " const";
@@ -1324,14 +1328,14 @@ class NonTypeTemplateParamDecl final : public Node {
template<typename Fn> void match(Fn F) const { F(Name, Type); }
void printLeft(OutputBuffer &OB) const override {
- Type->printLeft(OB);
+ OB.printLeft(*Type);
if (!Type->hasRHSComponent(OB))
OB += " ";
}
void printRight(OutputBuffer &OB) const override {
Name->print(OB);
- Type->printRight(OB);
+ OB.printRight(*Type);
}
};
@@ -1376,11 +1380,11 @@ class TemplateParamPackDecl final : public Node {
template<typename Fn> void match(Fn F) const { F(Param); }
void printLeft(OutputBuffer &OB) const override {
- Param->printLeft(OB);
+ OB.printLeft(*Param);
OB += "...";
}
- void printRight(OutputBuffer &OB) const override { Param->printRight(OB); }
+ void printRight(OutputBuffer &OB) const override { OB.printRight(*Param); }
};
/// An unexpanded parameter pack (either in the expression or type context). If
@@ -1445,13 +1449,13 @@ class ParameterPack final : public Node {
initializePackExpansion(OB);
size_t Idx = OB.CurrentPackIndex;
if (Idx < Data.size())
- Data[Idx]->printLeft(OB);
+ OB.printLeft(*Data[Idx]);
}
void printRight(OutputBuffer &OB) const override {
initializePackExpansion(OB);
size_t Idx = OB.CurrentPackIndex;
if (Idx < Data.size())
- Data[Idx]->printRight(OB);
+ OB.printRight(*Data[Idx]);
}
};
@@ -1609,13 +1613,13 @@ struct ForwardTemplateReference : Node {
if (Printing)
return;
ScopedOverride<bool> SavePrinting(Printing, true);
- Ref->printLeft(OB);
+ OB.printLeft(*Ref);
}
void printRight(OutputBuffer &OB) const override {
if (Printing)
return;
ScopedOverride<bool> SavePrinting(Printing, true);
- Ref->printRight(OB);
+ OB.printRight(*Ref);
}
};
@@ -1767,7 +1771,7 @@ class DtorName : public Node {
void printLeft(OutputBuffer &OB) const override {
OB += "~";
- Base->printLeft(OB);
+ OB.printLeft(*Base);
}
};
@@ -2047,7 +2051,7 @@ class CastExpr : public Node {
{
ScopedOverride<unsigned> LT(OB.GtIsGt, 0);
OB += "<";
- To->printLeft(OB);
+ OB.printLeft(*To);
OB += ">";
}
OB.printOpen();
@@ -6176,6 +6180,10 @@ struct ManglingParser : AbstractManglingParser<ManglingParser<Alloc>, Alloc> {
Alloc>::AbstractManglingParser;
};
+inline void OutputBuffer::printLeft(const Node &N) { N.printLeft(*this); }
+
+inline void OutputBuffer::printRight(const Node &N) { N.printRight(*this); }
+
DEMANGLE_NAMESPACE_END
#if defined(__clang__)
diff --git a/libcxxabi/src/demangle/Utility.h b/libcxxabi/src/demangle/Utility.h
index f1fad35d60d98..a38bef762dd57 100644
--- a/libcxxabi/src/demangle/Utility.h
+++ b/libcxxabi/src/demangle/Utility.h
@@ -27,6 +27,8 @@
DEMANGLE_NAMESPACE_BEGIN
+class Node;
+
// Stream that AST nodes write their string representation into after the AST
// has been parsed.
class OutputBuffer {
@@ -79,10 +81,15 @@ class OutputBuffer {
OutputBuffer(const OutputBuffer &) = delete;
OutputBuffer &operator=(const OutputBuffer &) = delete;
+ virtual ~OutputBuffer() {}
+
operator std::string_view() const {
return std::string_view(Buffer, CurrentPosition);
}
+ virtual void printLeft(const Node &N);
+ virtual void printRight(const Node &N);
+
/// If a ParameterPackExpansion (or similar type) is encountered, the offset
/// into the pack that we're currently printing.
unsigned CurrentPackIndex = std::numeric_limits<unsigned>::max();
diff --git a/lldb/include/lldb/Core/DemangledNameInfo.h b/lldb/include/lldb/Core/DemangledNameInfo.h
new file mode 100644
index 0000000000000..8acb25518cdd3
--- /dev/null
+++ b/lldb/include/lldb/Core/DemangledNameInfo.h
@@ -0,0 +1,151 @@
+//===-- DemangledNameInfo.h -------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_CORE_DEMANGLEDNAMEINFO_H
+#define LLDB_CORE_DEMANGLEDNAMEINFO_H
+
+#include "llvm/Demangle/ItaniumDemangle.h"
+#include "llvm/Demangle/Utility.h"
+
+#include <cstddef>
+#include <utility>
+
+namespace lldb_private {
+
+/// Stores information about where certain portions of a demangled
+/// function name begin and end.
+struct DemangledNameInfo {
+ /// A [start, end) pair for the function basename.
+ /// The basename is the name without scope qualifiers
+ /// and without template parameters. E.g.,
+ /// \code{.cpp}
+ /// void foo::bar<int>::someFunc<float>(int) const &&
+ /// ^ ^
+ /// start end
+ /// \endcode
+ std::pair<size_t, size_t> BasenameRange;
+
+ /// A [start, end) pair for the function scope qualifiers.
+ /// E.g., for
+ /// \code{.cpp}
+ /// void foo::bar<int>::qux<float>(int) const &&
+ /// ^ ^
+ /// start end
+ /// \endcode
+ std::pair<size_t, size_t> ScopeRange;
+
+ /// Indicates the [start, end) of the function argument lits.
+ /// E.g.,
+ /// \code{.cpp}
+ /// int (*getFunc<float>(float, double))(int, int)
+ /// ^ ^
+ /// start end
+ /// \endcode
+ std::pair<size_t, size_t> ArgumentsRange;
+
+ /// Returns \c true if this object holds a valid basename range.
+ bool hasBasename() const {
+ return BasenameRange.first != BasenameRange.second &&
+ BasenameRange.second > 0;
+ }
+
+ friend bool operator==(const DemangledNameInfo &lhs,
+ const DemangledNameInfo &rhs) {
+ return std::tie(lhs.BasenameRange, lhs.ArgumentsRange, lhs.ScopeRange) ==
+ std::tie(rhs.BasenameRange, rhs.ArgumentsRange, rhs.ScopeRange);
+ }
+
+ friend bool operator!=(const DemangledNameInfo &lhs,
+ const DemangledNameInfo &rhs) {
+ return !(lhs == rhs);
+ }
+};
+
+/// An OutputBuffer which keeps a record of where certain parts of a
+/// demangled name begin/end (e.g., basename, scope, argument list, etc.).
+/// The tracking occurs during printing of the Itanium demangle tree.
+///
+/// Usage:
+/// \code{.cpp}
+///
+/// Node *N = mangling_parser.parseType();
+///
+/// TrackingOutputBuffer buffer;
+/// N->printLeft(OB);
+///
+/// assert (buffer.NameInfo.hasBasename());
+///
+/// \endcode
+struct TrackingOutputBuffer : public llvm::itanium_demangle::OutputBuffer {
+ using OutputBuffer::OutputBuffer;
+
+ /// Holds information about the demangled name that is
+ /// being printed into this buffer.
+ DemangledNameInfo NameInfo;
+
+ void printLeft(const llvm::itanium_demangle::Node &N) override;
+ void printRight(const llvm::itanium_demangle::Node &N) override;
+
+private:
+ void printLeftImpl(const llvm::itanium_demangle::FunctionType &N);
+ void printRightImpl(const llvm::itanium_demangle::FunctionType &N);
+
+ void printLeftImpl(const llvm::itanium_demangle::FunctionEncoding &N);
+ void printRightImpl(const llvm::itanium_demangle::FunctionEncoding &N);
+
+ void printLeftImpl(const llvm::itanium_demangle::NestedName &N);
+ void printLeftImpl(const llvm::itanium_demangle::NameWithTemplateArgs &N);
+
+ /// Called whenever we start printing a function type in the Itanium
+ /// mangling scheme. Examples include \ref FunctionEncoding, \ref
+ /// FunctionType, etc.
+ ///
+ /// \returns A ScopedOverride which will update the nesting depth of
+ /// currently printed function types on destruction.
+ [[nodiscard]] llvm::itanium_demangle::ScopedOverride<unsigned>
+ enterFunctionTypePrinting();
+
+ /// Returns \c true if we're not printing any nested function types,
+ /// just a \ref FunctionEncoding in the Itanium mangling scheme.
+ bool isPrintingTopLevelFunctionType() const;
+
+ /// If this object \ref shouldTrack, then update the end of
+ /// the basename range to the current \c OB position.
+ void updateBasenameEnd();
+
+ /// If this object \ref shouldTrack, then update the beginning
+ /// of the scope range to the current \c OB position.
+ void updateScopeStart();
+
+ /// If this object \ref shouldTrack, then update the end of
+ /// the scope range to the current \c OB position.
+ void updateScopeEnd();
+
+ /// Returns \c true if the members of this object can be
+ /// updated. E.g., when we're printing nested template
+ /// arguments, we don't need to be tracking basename
+ /// locations.
+ bool shouldTrack() const;
+
+ /// Helpers alled to track beginning and end of the function
+ /// arguments.
+ void finalizeArgumentEnd();
+ void finalizeStart();
+ void finalizeEnd();
+
+ /// Helper used in the finalize APIs.
+ bool canFinalize() const;
+
+ /// Incremented each time we start printing a function type node
+ /// in the Itanium mangling scheme (e.g., \ref FunctionEncoding
+ /// or \ref FunctionType).
+ unsigned FunctionPrintingDepth = 0;
+};
+} // namespace lldb_private
+
+#endif // LLDB_CORE_DEMANGLEDNAMEINFO_H
diff --git a/lldb/include/lldb/Core/FormatEntity.h b/lldb/include/lldb/Core/FormatEntity.h
index 51e9ce37e54e7..3ca744f4e047e 100644
--- a/lldb/include/lldb/Core/FormatEntity.h
+++ b/lldb/include/lldb/Core/FormatEntity.h
@@ -199,6 +199,26 @@ struct Entry {
return true;
}
+ /// Describes how a function name should be highlighted.
+ struct HighlightSettings {
+ /// ANSI prefix that will be printed before the function name.
+ std::string prefix;
+
+ /// ANSI suffix that will be printed after the function name.
+ std::string suffix;
+
+ /// What kind of highlighting the user asked to perform.
+ enum class Kind : uint8_t {
+ ///< Don't highlight.
+ None,
+
+ ///< Highlight function basename
+ ///< (i.e., name without Scope and
+ ///< without template arguments).
+ Basename,
+ } kind = Kind::None;
+ };
+
std::string string;
std::string printf_format;
std::vector<Entry> children;
@@ -206,6 +226,14 @@ struct Entry {
lldb::Format fmt = lldb::eFormatDefault;
lldb::addr_t number = 0;
bool deref = false;
+
+ /// Set using the highlighting format specifiers to a
+ /// frame-format variable.
+ /// E.g.,
+ /// \code
+ /// ${function.name-with-args:%highlight_basename(ansi.fg.green)}
+ /// \endcode
+ HighlightSettings highlight;
};
bool Format(const Entry &entry, Stream &s, const SymbolContext *sc,
diff --git a/lldb/include/lldb/Core/Mangled.h b/lldb/include/lldb/Core/Mangled.h
index 5988d919a89b8..6f4ed741e8c5e 100644
--- a/lldb/include/lldb/Core/Mangled.h
+++ b/lldb/include/lldb/Core/Mangled.h
@@ -9,10 +9,11 @@
#ifndef LLDB_CORE_MANGLED_H
#define LLDB_CORE_MANGLED_H
+#include "lldb/Core/DemangledNameInfo.h"
+#include "lldb/Utility/ConstString.h"
#include "lldb/lldb-enumerations.h"
#include "lldb/lldb-forward.h"
#include "lldb/lldb-types.h"
-#include "lldb/Utility/ConstString.h"
#include "llvm/ADT/StringRef.h"
#include <cstddef>
@@ -134,9 +135,15 @@ class Mangled {
/// A const reference to the display demangled name string object.
ConstString GetDisplayDemangledName() const;
- void SetDemangledName(ConstString name) { m_demangled = name; }
+ void SetDemangledName(ConstString name) {
+ m_demangled = name;
+ m_demangled_info.reset();
+ }
- void SetMangledName(ConstString name) { m_mangled = name; }
+ void SetMangledName(ConstString name) {
+ m_mangled = name;
+ m_demangled_info.reset();
+ }
/// Mangled name get accessor.
///
@@ -275,13 +282,26 @@ class Mangled {
/// table offsets in the cache data.
void Encode(DataEncoder &encoder, ConstStringTable &strtab) const;
+ /// Retrieve \c DemangledNameInfo of the demangled name held by this object.
+ const std::optional<DemangledNameInfo> &GetDemangledInfo() const;
+
private:
+ /// If \c force is \c false, this function will re-use the previously
+ /// demangled name (if any). If \c force is \c true (or the mangled name
+ /// on this object was not previously demangled), demangle and cache the
+ /// name.
+ ConstString GetDemangledNameImpl(bool force) const;
+
/// The mangled version of the name.
ConstString m_mangled;
/// Mutable so we can get it on demand with
/// a const version of this object.
mutable ConstString m_demangled;
+
+ /// If available, holds information about where in \c m_demangled certain
+ /// parts of the name (e.g., basename, arguments, etc.) begin and end.
+ mutable std::optional<DemangledNameInfo> m_demangled_info = std::nullopt;
};
Stream &operator<<(Stream &s, const Mangled &obj);
diff --git a/lldb/include/lldb/Symbol/Function.h b/lldb/include/lldb/Symbol/Function.h
index 21b3f9ab4a70c..62796b1538d26 100644
--- a/lldb/include/lldb/Symbol/Function.h
+++ b/lldb/include/lldb/Symbol/Function.h
@@ -11,6 +11,7 @@
#include "lldb/Core/AddressRange.h"
#include "lldb/Core/Declaration.h"
+#include "lldb/Core/DemangledNameInfo.h"
#include "lldb/Core/Mangled.h"
#include "lldb/Expression/DWARFExpressionList.h"
#include "lldb/Symbol/Block.h"
@@ -531,6 +532,9 @@ class Function : public UserID, public SymbolContextScope {
ConstString GetDisplayName() const;
+ /// Retrieve \c DemangledNameInfo of the demangled name held by this object.
+ const std::optional<DemangledNameInfo> &GetDemangledInfo() const;
+
const Mangled &GetMangled() const { return m_mangled; }
/// Get the DeclContext for this function, if available.
diff --git a/lldb/include/lldb/Target/Language.h b/lldb/include/lldb/Target/Language.h
index b699a90aff8e4..088aa1a964ec7 100644
--- a/lldb/include/lldb/Target/Language.h
+++ b/lldb/include/lldb/Target/Language.h
@@ -268,10 +268,11 @@ class Language : public PluginInterface {
// the reference has never been assigned
virtual bool IsUninitializedReference(ValueObject &valobj);
- virtual bool GetFunctionDisplayName(const SymbolContext *sc,
- const ExecutionContext *exe_ctx,
- FunctionNameRepresentation representation,
- Stream &s);
+ virtual bool
+ GetFunctionDisplayName(const SymbolContext *sc,
+ const ExecutionContext *exe_ctx,
+ FunctionNameRepresentation representation, Stream &s,
+ const FormatEntity::Entry::HighlightSettings &);
virtual ConstString
GetDemangledFunctionNameWithoutArguments(Mangled mangled) const {
diff --git a/lldb/source/Core/CMakeLists.txt b/lldb/source/Core/CMakeLists.txt
index 0a08da0fec230...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/131836
More information about the llvm-commits
mailing list