[Lldb-commits] [lldb] 406f61f - [lldb][CPlusPlusLanguage] Create public accessors for getting DemangledNameInfo components and use them in tests (#152134)
via lldb-commits
lldb-commits at lists.llvm.org
Tue Aug 5 10:12:26 PDT 2025
Author: Michael Buch
Date: 2025-08-05T18:12:22+01:00
New Revision: 406f61fd3a28b9628f50cf009c6e65562f93a2cc
URL: https://github.com/llvm/llvm-project/commit/406f61fd3a28b9628f50cf009c6e65562f93a2cc
DIFF: https://github.com/llvm/llvm-project/commit/406f61fd3a28b9628f50cf009c6e65562f93a2cc.diff
LOG: [lldb][CPlusPlusLanguage] Create public accessors for getting DemangledNameInfo components and use them in tests (#152134)
This way we make sure that the logic to reconstruct demangled names in
the tests is the same as the logic when reconstructing the actual
frame-format variable.
`DemangledNameInfo::SuffixRange` is currently the only one which we
can't test in the same way until we set it from inside the
`TrackingOutputBuffer`. I added TODOs to track this.
Added:
Modified:
lldb/source/Core/Mangled.cpp
lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
lldb/unittests/Core/MangledTest.cpp
Removed:
################################################################################
diff --git a/lldb/source/Core/Mangled.cpp b/lldb/source/Core/Mangled.cpp
index 0027bfaeda4f7..3663f430111c2 100644
--- a/lldb/source/Core/Mangled.cpp
+++ b/lldb/source/Core/Mangled.cpp
@@ -172,6 +172,7 @@ GetItaniumDemangledStr(const char *M) {
TrackingOutputBuffer OB(demangled_cstr, demangled_size);
demangled_cstr = ipd.finishDemangle(&OB);
+ // TODO: we should set the SuffixRange inside the TrackingOutputBuffer.
OB.NameInfo.SuffixRange.first = OB.NameInfo.QualifiersRange.second;
OB.NameInfo.SuffixRange.second = std::string_view(OB).size();
info = std::move(OB.NameInfo);
diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index 3353d5a898898..3bc870810dc81 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -19,6 +19,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/Demangle/ItaniumDemangle.h"
+#include "lldb/Core/DemangledNameInfo.h"
#include "lldb/Core/Mangled.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
@@ -271,8 +272,25 @@ GetDemangledBasename(const SymbolContext &sc) {
auto [demangled_name, info] = *info_or_err;
- return demangled_name.slice(info.BasenameRange.first,
- info.BasenameRange.second);
+ return CPlusPlusLanguage::GetDemangledBasename(demangled_name, info);
+}
+
+llvm::StringRef
+CPlusPlusLanguage::GetDemangledBasename(llvm::StringRef demangled,
+ const DemangledNameInfo &info) {
+ assert(info.hasBasename());
+ return demangled.slice(info.BasenameRange.first, info.BasenameRange.second);
+}
+
+llvm::Expected<llvm::StringRef>
+CPlusPlusLanguage::GetDemangledTemplateArguments(
+ llvm::StringRef demangled, const DemangledNameInfo &info) {
+ if (!info.hasTemplateArguments())
+ return llvm::createStringError(
+ "Template arguments range for '%s' is invalid.", demangled.data());
+
+ return demangled.slice(info.TemplateArgumentsRange.first,
+ info.TemplateArgumentsRange.second);
}
static llvm::Expected<llvm::StringRef>
@@ -283,12 +301,17 @@ GetDemangledTemplateArguments(const SymbolContext &sc) {
auto [demangled_name, info] = *info_or_err;
- if (!info.hasTemplateArguments())
+ return CPlusPlusLanguage::GetDemangledTemplateArguments(demangled_name, info);
+}
+
+llvm::Expected<llvm::StringRef>
+CPlusPlusLanguage::GetDemangledReturnTypeLHS(llvm::StringRef demangled,
+ const DemangledNameInfo &info) {
+ if (info.ScopeRange.first >= demangled.size())
return llvm::createStringError(
- "Template arguments range for '%s' is invalid.", demangled_name.data());
+ "Scope range for '%s' LHS return type is invalid.", demangled.data());
- return demangled_name.slice(info.TemplateArgumentsRange.first,
- info.TemplateArgumentsRange.second);
+ return demangled.substr(0, info.ScopeRange.first);
}
static llvm::Expected<llvm::StringRef>
@@ -299,12 +322,18 @@ GetDemangledReturnTypeLHS(const SymbolContext &sc) {
auto [demangled_name, info] = *info_or_err;
- if (info.ScopeRange.first >= demangled_name.size())
- return llvm::createStringError(
- "Scope range for '%s' LHS return type is invalid.",
- demangled_name.data());
+ return CPlusPlusLanguage::GetDemangledReturnTypeLHS(demangled_name, info);
+}
+
+llvm::Expected<llvm::StringRef>
+CPlusPlusLanguage::GetDemangledFunctionQualifiers(
+ llvm::StringRef demangled, const DemangledNameInfo &info) {
+ if (!info.hasQualifiers())
+ return llvm::createStringError("Qualifiers range for '%s' is invalid.",
+ demangled.data());
- return demangled_name.substr(0, info.ScopeRange.first);
+ return demangled.slice(info.QualifiersRange.first,
+ info.QualifiersRange.second);
}
static llvm::Expected<llvm::StringRef>
@@ -315,12 +344,20 @@ GetDemangledFunctionQualifiers(const SymbolContext &sc) {
auto [demangled_name, info] = *info_or_err;
- if (!info.hasQualifiers())
- return llvm::createStringError("Qualifiers range for '%s' is invalid.",
- demangled_name.data());
+ return CPlusPlusLanguage::GetDemangledFunctionQualifiers(demangled_name,
+ info);
+}
- return demangled_name.slice(info.QualifiersRange.first,
- info.QualifiersRange.second);
+llvm::Expected<llvm::StringRef>
+CPlusPlusLanguage::GetDemangledReturnTypeRHS(llvm::StringRef demangled,
+ const DemangledNameInfo &info) {
+ if (info.QualifiersRange.first < info.ArgumentsRange.second)
+ return llvm::createStringError(
+ "Qualifiers range for '%s' RHS return type is invalid.",
+ demangled.data());
+
+ return demangled.slice(info.ArgumentsRange.second,
+ info.QualifiersRange.first);
}
static llvm::Expected<llvm::StringRef>
@@ -331,13 +368,17 @@ GetDemangledReturnTypeRHS(const SymbolContext &sc) {
auto [demangled_name, info] = *info_or_err;
- if (info.QualifiersRange.first < info.ArgumentsRange.second)
- return llvm::createStringError(
- "Qualifiers range for '%s' RHS return type is invalid.",
- demangled_name.data());
+ return CPlusPlusLanguage::GetDemangledReturnTypeRHS(demangled_name, info);
+}
- return demangled_name.slice(info.ArgumentsRange.second,
- info.QualifiersRange.first);
+llvm::Expected<llvm::StringRef>
+CPlusPlusLanguage::GetDemangledScope(llvm::StringRef demangled,
+ const DemangledNameInfo &info) {
+ if (!info.hasScope())
+ return llvm::createStringError("Scope range for '%s' is invalid.",
+ demangled.data());
+
+ return demangled.slice(info.ScopeRange.first, info.ScopeRange.second);
}
static llvm::Expected<llvm::StringRef>
@@ -348,15 +389,16 @@ GetDemangledScope(const SymbolContext &sc) {
auto [demangled_name, info] = *info_or_err;
- if (!info.hasScope())
- return llvm::createStringError("Scope range for '%s' is invalid.",
- demangled_name.data());
-
- return demangled_name.slice(info.ScopeRange.first, info.ScopeRange.second);
+ return CPlusPlusLanguage::GetDemangledScope(demangled_name, info);
}
/// Handles anything printed after the FunctionEncoding ItaniumDemangle
-/// node. Most notably the DotSUffix node.
+/// node. Most notably the DotSuffix node.
+///
+/// FIXME: the suffix should also have an associated
+/// CPlusPlusLanguage::GetDemangledFunctionSuffix
+/// once we start setting the `DemangledNameInfo::SuffixRange`
+/// from inside the `TrackingOutputBuffer`.
static llvm::Expected<llvm::StringRef>
GetDemangledFunctionSuffix(const SymbolContext &sc) {
auto info_or_err = GetAndValidateInfo(sc);
@@ -372,6 +414,16 @@ GetDemangledFunctionSuffix(const SymbolContext &sc) {
return demangled_name.slice(info.SuffixRange.first, info.SuffixRange.second);
}
+llvm::Expected<llvm::StringRef>
+CPlusPlusLanguage::GetDemangledFunctionArguments(
+ llvm::StringRef demangled, const DemangledNameInfo &info) {
+ if (!info.hasArguments())
+ return llvm::createStringError(
+ "Function arguments range for '%s' is invalid.", demangled.data());
+
+ return demangled.slice(info.ArgumentsRange.first, info.ArgumentsRange.second);
+}
+
static bool PrintDemangledArgumentList(Stream &s, const SymbolContext &sc) {
assert(sc.symbol);
@@ -382,13 +434,19 @@ static bool PrintDemangledArgumentList(Stream &s, const SymbolContext &sc) {
"frame-format variable: {0}");
return false;
}
+
auto [demangled_name, info] = *info_or_err;
- if (!info.hasArguments())
+ auto args_or_err =
+ CPlusPlusLanguage::GetDemangledFunctionArguments(demangled_name, info);
+ if (!args_or_err) {
+ LLDB_LOG_ERROR(GetLog(LLDBLog::Language), args_or_err.takeError(),
+ "Failed to handle ${{function.formatted-arguments}} "
+ "frame-format variable: {0}");
return false;
+ }
- s << demangled_name.slice(info.ArgumentsRange.first,
- info.ArgumentsRange.second);
+ s << *args_or_err;
return true;
}
@@ -2261,7 +2319,7 @@ bool CPlusPlusLanguage::HandleFrameFormatVariable(
FormatEntity::Entry::Type type, Stream &s) {
switch (type) {
case FormatEntity::Entry::Type::FunctionScope: {
- auto scope_or_err = GetDemangledScope(sc);
+ auto scope_or_err = ::GetDemangledScope(sc);
if (!scope_or_err) {
LLDB_LOG_ERROR(
GetLog(LLDBLog::Language), scope_or_err.takeError(),
@@ -2275,7 +2333,7 @@ bool CPlusPlusLanguage::HandleFrameFormatVariable(
}
case FormatEntity::Entry::Type::FunctionBasename: {
- auto name_or_err = GetDemangledBasename(sc);
+ auto name_or_err = ::GetDemangledBasename(sc);
if (!name_or_err) {
LLDB_LOG_ERROR(
GetLog(LLDBLog::Language), name_or_err.takeError(),
@@ -2289,7 +2347,7 @@ bool CPlusPlusLanguage::HandleFrameFormatVariable(
}
case FormatEntity::Entry::Type::FunctionTemplateArguments: {
- auto template_args_or_err = GetDemangledTemplateArguments(sc);
+ auto template_args_or_err = ::GetDemangledTemplateArguments(sc);
if (!template_args_or_err) {
LLDB_LOG_ERROR(GetLog(LLDBLog::Language),
template_args_or_err.takeError(),
@@ -2327,7 +2385,7 @@ bool CPlusPlusLanguage::HandleFrameFormatVariable(
return true;
}
case FormatEntity::Entry::Type::FunctionReturnRight: {
- auto return_rhs_or_err = GetDemangledReturnTypeRHS(sc);
+ auto return_rhs_or_err = ::GetDemangledReturnTypeRHS(sc);
if (!return_rhs_or_err) {
LLDB_LOG_ERROR(GetLog(LLDBLog::Language), return_rhs_or_err.takeError(),
"Failed to handle ${{function.return-right}} frame-format "
@@ -2340,7 +2398,7 @@ bool CPlusPlusLanguage::HandleFrameFormatVariable(
return true;
}
case FormatEntity::Entry::Type::FunctionReturnLeft: {
- auto return_lhs_or_err = GetDemangledReturnTypeLHS(sc);
+ auto return_lhs_or_err = ::GetDemangledReturnTypeLHS(sc);
if (!return_lhs_or_err) {
LLDB_LOG_ERROR(GetLog(LLDBLog::Language), return_lhs_or_err.takeError(),
"Failed to handle ${{function.return-left}} frame-format "
@@ -2353,7 +2411,7 @@ bool CPlusPlusLanguage::HandleFrameFormatVariable(
return true;
}
case FormatEntity::Entry::Type::FunctionQualifiers: {
- auto quals_or_err = GetDemangledFunctionQualifiers(sc);
+ auto quals_or_err = ::GetDemangledFunctionQualifiers(sc);
if (!quals_or_err) {
LLDB_LOG_ERROR(GetLog(LLDBLog::Language), quals_or_err.takeError(),
"Failed to handle ${{function.qualifiers}} frame-format "
diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
index 22acdf3e8efe9..4f449f11257a6 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
+++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
@@ -112,6 +112,32 @@ class CPlusPlusLanguage : public Language {
static bool IsCPPMangledName(llvm::StringRef name);
+ static llvm::StringRef GetDemangledBasename(llvm::StringRef demangled,
+ const DemangledNameInfo &info);
+
+ static llvm::Expected<llvm::StringRef>
+ GetDemangledTemplateArguments(llvm::StringRef demangled,
+ const DemangledNameInfo &info);
+
+ static llvm::Expected<llvm::StringRef>
+ GetDemangledReturnTypeLHS(llvm::StringRef demangled,
+ const DemangledNameInfo &info);
+
+ static llvm::Expected<llvm::StringRef>
+ GetDemangledFunctionQualifiers(llvm::StringRef demangled,
+ const DemangledNameInfo &info);
+
+ static llvm::Expected<llvm::StringRef>
+ GetDemangledScope(llvm::StringRef demangled, const DemangledNameInfo &info);
+
+ static llvm::Expected<llvm::StringRef>
+ GetDemangledReturnTypeRHS(llvm::StringRef demangled,
+ const DemangledNameInfo &info);
+
+ static llvm::Expected<llvm::StringRef>
+ GetDemangledFunctionArguments(llvm::StringRef demangled,
+ const DemangledNameInfo &info);
+
// Extract C++ context and identifier from a string using heuristic matching
// (as opposed to
// CPlusPlusLanguage::CxxMethodName which has to have a fully qualified C++
diff --git a/lldb/unittests/Core/MangledTest.cpp b/lldb/unittests/Core/MangledTest.cpp
index eecef033aa349..a6e6e75fde145 100644
--- a/lldb/unittests/Core/MangledTest.cpp
+++ b/lldb/unittests/Core/MangledTest.cpp
@@ -6,6 +6,7 @@
//
//===----------------------------------------------------------------------===//
+#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
#include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
#include "Plugins/SymbolFile/Symtab/SymbolFileSymtab.h"
#include "TestingSupport/SubsystemRAII.h"
@@ -19,6 +20,7 @@
#include "lldb/Host/HostInfo.h"
#include "lldb/Symbol/SymbolContext.h"
+#include "llvm/Support/Error.h"
#include "llvm/Support/FileUtilities.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Program.h"
@@ -852,25 +854,45 @@ TEST_P(DemanglingInfoCorrectnessTestFixutre, Correctness) {
auto tracked_name = llvm::StringRef(*OB);
- auto return_left = tracked_name.slice(0, OB->NameInfo.ScopeRange.first);
- auto scope = tracked_name.slice(OB->NameInfo.ScopeRange.first,
- OB->NameInfo.ScopeRange.second);
- auto basename = tracked_name.slice(OB->NameInfo.BasenameRange.first,
- OB->NameInfo.BasenameRange.second);
- auto template_args = tracked_name.slice(OB->NameInfo.BasenameRange.second,
- OB->NameInfo.ArgumentsRange.first);
- auto args = tracked_name.slice(OB->NameInfo.ArgumentsRange.first,
- OB->NameInfo.ArgumentsRange.second);
- auto return_right = tracked_name.slice(OB->NameInfo.ArgumentsRange.second,
- OB->NameInfo.QualifiersRange.first);
- auto qualifiers = tracked_name.slice(OB->NameInfo.QualifiersRange.first,
- OB->NameInfo.QualifiersRange.second);
+ std::string reconstructed_name;
+
+ auto return_left =
+ CPlusPlusLanguage::GetDemangledReturnTypeLHS(tracked_name, OB->NameInfo);
+ EXPECT_THAT_EXPECTED(return_left, llvm::Succeeded());
+ reconstructed_name += *return_left;
+
+ auto scope = CPlusPlusLanguage::GetDemangledScope(tracked_name, OB->NameInfo);
+ EXPECT_THAT_EXPECTED(scope, llvm::Succeeded());
+ reconstructed_name += *scope;
+
+ auto basename =
+ CPlusPlusLanguage::GetDemangledBasename(tracked_name, OB->NameInfo);
+ reconstructed_name += basename;
+
+ auto template_args = CPlusPlusLanguage::GetDemangledTemplateArguments(
+ tracked_name, OB->NameInfo);
+ EXPECT_THAT_EXPECTED(template_args, llvm::Succeeded());
+ reconstructed_name += *template_args;
+
+ auto args = CPlusPlusLanguage::GetDemangledFunctionArguments(tracked_name,
+ OB->NameInfo);
+ EXPECT_THAT_EXPECTED(args, llvm::Succeeded());
+ reconstructed_name += *args;
+
+ auto return_right =
+ CPlusPlusLanguage::GetDemangledReturnTypeRHS(tracked_name, OB->NameInfo);
+ EXPECT_THAT_EXPECTED(return_right, llvm::Succeeded());
+ reconstructed_name += *return_right;
+
+ auto qualifiers = CPlusPlusLanguage::GetDemangledFunctionQualifiers(
+ tracked_name, OB->NameInfo);
+ EXPECT_THAT_EXPECTED(qualifiers, llvm::Succeeded());
+ reconstructed_name += *qualifiers;
+
+ // TODO: should retrieve suffix using the plugin too.
auto suffix = tracked_name.slice(OB->NameInfo.QualifiersRange.second,
llvm::StringRef::npos);
-
- auto reconstructed_name =
- llvm::join_items("", return_left, scope, basename, template_args, args,
- return_right, qualifiers, suffix);
+ reconstructed_name += suffix;
EXPECT_EQ(reconstructed_name, demangled);
}
More information about the lldb-commits
mailing list