Skip to content

Commit 406f61f

Browse files
authored
[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.
1 parent 3b2a1a5 commit 406f61f

File tree

4 files changed

+161
-54
lines changed

4 files changed

+161
-54
lines changed

lldb/source/Core/Mangled.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ GetItaniumDemangledStr(const char *M) {
172172

173173
TrackingOutputBuffer OB(demangled_cstr, demangled_size);
174174
demangled_cstr = ipd.finishDemangle(&OB);
175+
// TODO: we should set the SuffixRange inside the TrackingOutputBuffer.
175176
OB.NameInfo.SuffixRange.first = OB.NameInfo.QualifiersRange.second;
176177
OB.NameInfo.SuffixRange.second = std::string_view(OB).size();
177178
info = std::move(OB.NameInfo);

lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp

Lines changed: 95 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "llvm/ADT/StringRef.h"
2020
#include "llvm/Demangle/ItaniumDemangle.h"
2121

22+
#include "lldb/Core/DemangledNameInfo.h"
2223
#include "lldb/Core/Mangled.h"
2324
#include "lldb/Core/Module.h"
2425
#include "lldb/Core/PluginManager.h"
@@ -271,8 +272,25 @@ GetDemangledBasename(const SymbolContext &sc) {
271272

272273
auto [demangled_name, info] = *info_or_err;
273274

274-
return demangled_name.slice(info.BasenameRange.first,
275-
info.BasenameRange.second);
275+
return CPlusPlusLanguage::GetDemangledBasename(demangled_name, info);
276+
}
277+
278+
llvm::StringRef
279+
CPlusPlusLanguage::GetDemangledBasename(llvm::StringRef demangled,
280+
const DemangledNameInfo &info) {
281+
assert(info.hasBasename());
282+
return demangled.slice(info.BasenameRange.first, info.BasenameRange.second);
283+
}
284+
285+
llvm::Expected<llvm::StringRef>
286+
CPlusPlusLanguage::GetDemangledTemplateArguments(
287+
llvm::StringRef demangled, const DemangledNameInfo &info) {
288+
if (!info.hasTemplateArguments())
289+
return llvm::createStringError(
290+
"Template arguments range for '%s' is invalid.", demangled.data());
291+
292+
return demangled.slice(info.TemplateArgumentsRange.first,
293+
info.TemplateArgumentsRange.second);
276294
}
277295

278296
static llvm::Expected<llvm::StringRef>
@@ -283,12 +301,17 @@ GetDemangledTemplateArguments(const SymbolContext &sc) {
283301

284302
auto [demangled_name, info] = *info_or_err;
285303

286-
if (!info.hasTemplateArguments())
304+
return CPlusPlusLanguage::GetDemangledTemplateArguments(demangled_name, info);
305+
}
306+
307+
llvm::Expected<llvm::StringRef>
308+
CPlusPlusLanguage::GetDemangledReturnTypeLHS(llvm::StringRef demangled,
309+
const DemangledNameInfo &info) {
310+
if (info.ScopeRange.first >= demangled.size())
287311
return llvm::createStringError(
288-
"Template arguments range for '%s' is invalid.", demangled_name.data());
312+
"Scope range for '%s' LHS return type is invalid.", demangled.data());
289313

290-
return demangled_name.slice(info.TemplateArgumentsRange.first,
291-
info.TemplateArgumentsRange.second);
314+
return demangled.substr(0, info.ScopeRange.first);
292315
}
293316

294317
static llvm::Expected<llvm::StringRef>
@@ -299,12 +322,18 @@ GetDemangledReturnTypeLHS(const SymbolContext &sc) {
299322

300323
auto [demangled_name, info] = *info_or_err;
301324

302-
if (info.ScopeRange.first >= demangled_name.size())
303-
return llvm::createStringError(
304-
"Scope range for '%s' LHS return type is invalid.",
305-
demangled_name.data());
325+
return CPlusPlusLanguage::GetDemangledReturnTypeLHS(demangled_name, info);
326+
}
327+
328+
llvm::Expected<llvm::StringRef>
329+
CPlusPlusLanguage::GetDemangledFunctionQualifiers(
330+
llvm::StringRef demangled, const DemangledNameInfo &info) {
331+
if (!info.hasQualifiers())
332+
return llvm::createStringError("Qualifiers range for '%s' is invalid.",
333+
demangled.data());
306334

307-
return demangled_name.substr(0, info.ScopeRange.first);
335+
return demangled.slice(info.QualifiersRange.first,
336+
info.QualifiersRange.second);
308337
}
309338

310339
static llvm::Expected<llvm::StringRef>
@@ -315,12 +344,20 @@ GetDemangledFunctionQualifiers(const SymbolContext &sc) {
315344

316345
auto [demangled_name, info] = *info_or_err;
317346

318-
if (!info.hasQualifiers())
319-
return llvm::createStringError("Qualifiers range for '%s' is invalid.",
320-
demangled_name.data());
347+
return CPlusPlusLanguage::GetDemangledFunctionQualifiers(demangled_name,
348+
info);
349+
}
321350

322-
return demangled_name.slice(info.QualifiersRange.first,
323-
info.QualifiersRange.second);
351+
llvm::Expected<llvm::StringRef>
352+
CPlusPlusLanguage::GetDemangledReturnTypeRHS(llvm::StringRef demangled,
353+
const DemangledNameInfo &info) {
354+
if (info.QualifiersRange.first < info.ArgumentsRange.second)
355+
return llvm::createStringError(
356+
"Qualifiers range for '%s' RHS return type is invalid.",
357+
demangled.data());
358+
359+
return demangled.slice(info.ArgumentsRange.second,
360+
info.QualifiersRange.first);
324361
}
325362

326363
static llvm::Expected<llvm::StringRef>
@@ -331,13 +368,17 @@ GetDemangledReturnTypeRHS(const SymbolContext &sc) {
331368

332369
auto [demangled_name, info] = *info_or_err;
333370

334-
if (info.QualifiersRange.first < info.ArgumentsRange.second)
335-
return llvm::createStringError(
336-
"Qualifiers range for '%s' RHS return type is invalid.",
337-
demangled_name.data());
371+
return CPlusPlusLanguage::GetDemangledReturnTypeRHS(demangled_name, info);
372+
}
338373

339-
return demangled_name.slice(info.ArgumentsRange.second,
340-
info.QualifiersRange.first);
374+
llvm::Expected<llvm::StringRef>
375+
CPlusPlusLanguage::GetDemangledScope(llvm::StringRef demangled,
376+
const DemangledNameInfo &info) {
377+
if (!info.hasScope())
378+
return llvm::createStringError("Scope range for '%s' is invalid.",
379+
demangled.data());
380+
381+
return demangled.slice(info.ScopeRange.first, info.ScopeRange.second);
341382
}
342383

343384
static llvm::Expected<llvm::StringRef>
@@ -348,15 +389,16 @@ GetDemangledScope(const SymbolContext &sc) {
348389

349390
auto [demangled_name, info] = *info_or_err;
350391

351-
if (!info.hasScope())
352-
return llvm::createStringError("Scope range for '%s' is invalid.",
353-
demangled_name.data());
354-
355-
return demangled_name.slice(info.ScopeRange.first, info.ScopeRange.second);
392+
return CPlusPlusLanguage::GetDemangledScope(demangled_name, info);
356393
}
357394

358395
/// Handles anything printed after the FunctionEncoding ItaniumDemangle
359-
/// node. Most notably the DotSUffix node.
396+
/// node. Most notably the DotSuffix node.
397+
///
398+
/// FIXME: the suffix should also have an associated
399+
/// CPlusPlusLanguage::GetDemangledFunctionSuffix
400+
/// once we start setting the `DemangledNameInfo::SuffixRange`
401+
/// from inside the `TrackingOutputBuffer`.
360402
static llvm::Expected<llvm::StringRef>
361403
GetDemangledFunctionSuffix(const SymbolContext &sc) {
362404
auto info_or_err = GetAndValidateInfo(sc);
@@ -372,6 +414,16 @@ GetDemangledFunctionSuffix(const SymbolContext &sc) {
372414
return demangled_name.slice(info.SuffixRange.first, info.SuffixRange.second);
373415
}
374416

417+
llvm::Expected<llvm::StringRef>
418+
CPlusPlusLanguage::GetDemangledFunctionArguments(
419+
llvm::StringRef demangled, const DemangledNameInfo &info) {
420+
if (!info.hasArguments())
421+
return llvm::createStringError(
422+
"Function arguments range for '%s' is invalid.", demangled.data());
423+
424+
return demangled.slice(info.ArgumentsRange.first, info.ArgumentsRange.second);
425+
}
426+
375427
static bool PrintDemangledArgumentList(Stream &s, const SymbolContext &sc) {
376428
assert(sc.symbol);
377429

@@ -382,13 +434,19 @@ static bool PrintDemangledArgumentList(Stream &s, const SymbolContext &sc) {
382434
"frame-format variable: {0}");
383435
return false;
384436
}
437+
385438
auto [demangled_name, info] = *info_or_err;
386439

387-
if (!info.hasArguments())
440+
auto args_or_err =
441+
CPlusPlusLanguage::GetDemangledFunctionArguments(demangled_name, info);
442+
if (!args_or_err) {
443+
LLDB_LOG_ERROR(GetLog(LLDBLog::Language), args_or_err.takeError(),
444+
"Failed to handle ${{function.formatted-arguments}} "
445+
"frame-format variable: {0}");
388446
return false;
447+
}
389448

390-
s << demangled_name.slice(info.ArgumentsRange.first,
391-
info.ArgumentsRange.second);
449+
s << *args_or_err;
392450

393451
return true;
394452
}
@@ -2261,7 +2319,7 @@ bool CPlusPlusLanguage::HandleFrameFormatVariable(
22612319
FormatEntity::Entry::Type type, Stream &s) {
22622320
switch (type) {
22632321
case FormatEntity::Entry::Type::FunctionScope: {
2264-
auto scope_or_err = GetDemangledScope(sc);
2322+
auto scope_or_err = ::GetDemangledScope(sc);
22652323
if (!scope_or_err) {
22662324
LLDB_LOG_ERROR(
22672325
GetLog(LLDBLog::Language), scope_or_err.takeError(),
@@ -2275,7 +2333,7 @@ bool CPlusPlusLanguage::HandleFrameFormatVariable(
22752333
}
22762334

22772335
case FormatEntity::Entry::Type::FunctionBasename: {
2278-
auto name_or_err = GetDemangledBasename(sc);
2336+
auto name_or_err = ::GetDemangledBasename(sc);
22792337
if (!name_or_err) {
22802338
LLDB_LOG_ERROR(
22812339
GetLog(LLDBLog::Language), name_or_err.takeError(),
@@ -2289,7 +2347,7 @@ bool CPlusPlusLanguage::HandleFrameFormatVariable(
22892347
}
22902348

22912349
case FormatEntity::Entry::Type::FunctionTemplateArguments: {
2292-
auto template_args_or_err = GetDemangledTemplateArguments(sc);
2350+
auto template_args_or_err = ::GetDemangledTemplateArguments(sc);
22932351
if (!template_args_or_err) {
22942352
LLDB_LOG_ERROR(GetLog(LLDBLog::Language),
22952353
template_args_or_err.takeError(),
@@ -2327,7 +2385,7 @@ bool CPlusPlusLanguage::HandleFrameFormatVariable(
23272385
return true;
23282386
}
23292387
case FormatEntity::Entry::Type::FunctionReturnRight: {
2330-
auto return_rhs_or_err = GetDemangledReturnTypeRHS(sc);
2388+
auto return_rhs_or_err = ::GetDemangledReturnTypeRHS(sc);
23312389
if (!return_rhs_or_err) {
23322390
LLDB_LOG_ERROR(GetLog(LLDBLog::Language), return_rhs_or_err.takeError(),
23332391
"Failed to handle ${{function.return-right}} frame-format "
@@ -2340,7 +2398,7 @@ bool CPlusPlusLanguage::HandleFrameFormatVariable(
23402398
return true;
23412399
}
23422400
case FormatEntity::Entry::Type::FunctionReturnLeft: {
2343-
auto return_lhs_or_err = GetDemangledReturnTypeLHS(sc);
2401+
auto return_lhs_or_err = ::GetDemangledReturnTypeLHS(sc);
23442402
if (!return_lhs_or_err) {
23452403
LLDB_LOG_ERROR(GetLog(LLDBLog::Language), return_lhs_or_err.takeError(),
23462404
"Failed to handle ${{function.return-left}} frame-format "
@@ -2353,7 +2411,7 @@ bool CPlusPlusLanguage::HandleFrameFormatVariable(
23532411
return true;
23542412
}
23552413
case FormatEntity::Entry::Type::FunctionQualifiers: {
2356-
auto quals_or_err = GetDemangledFunctionQualifiers(sc);
2414+
auto quals_or_err = ::GetDemangledFunctionQualifiers(sc);
23572415
if (!quals_or_err) {
23582416
LLDB_LOG_ERROR(GetLog(LLDBLog::Language), quals_or_err.takeError(),
23592417
"Failed to handle ${{function.qualifiers}} frame-format "

lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,32 @@ class CPlusPlusLanguage : public Language {
112112

113113
static bool IsCPPMangledName(llvm::StringRef name);
114114

115+
static llvm::StringRef GetDemangledBasename(llvm::StringRef demangled,
116+
const DemangledNameInfo &info);
117+
118+
static llvm::Expected<llvm::StringRef>
119+
GetDemangledTemplateArguments(llvm::StringRef demangled,
120+
const DemangledNameInfo &info);
121+
122+
static llvm::Expected<llvm::StringRef>
123+
GetDemangledReturnTypeLHS(llvm::StringRef demangled,
124+
const DemangledNameInfo &info);
125+
126+
static llvm::Expected<llvm::StringRef>
127+
GetDemangledFunctionQualifiers(llvm::StringRef demangled,
128+
const DemangledNameInfo &info);
129+
130+
static llvm::Expected<llvm::StringRef>
131+
GetDemangledScope(llvm::StringRef demangled, const DemangledNameInfo &info);
132+
133+
static llvm::Expected<llvm::StringRef>
134+
GetDemangledReturnTypeRHS(llvm::StringRef demangled,
135+
const DemangledNameInfo &info);
136+
137+
static llvm::Expected<llvm::StringRef>
138+
GetDemangledFunctionArguments(llvm::StringRef demangled,
139+
const DemangledNameInfo &info);
140+
115141
// Extract C++ context and identifier from a string using heuristic matching
116142
// (as opposed to
117143
// CPlusPlusLanguage::CxxMethodName which has to have a fully qualified C++

lldb/unittests/Core/MangledTest.cpp

Lines changed: 39 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9+
#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
910
#include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
1011
#include "Plugins/SymbolFile/Symtab/SymbolFileSymtab.h"
1112
#include "TestingSupport/SubsystemRAII.h"
@@ -19,6 +20,7 @@
1920
#include "lldb/Host/HostInfo.h"
2021
#include "lldb/Symbol/SymbolContext.h"
2122

23+
#include "llvm/Support/Error.h"
2224
#include "llvm/Support/FileUtilities.h"
2325
#include "llvm/Support/Path.h"
2426
#include "llvm/Support/Program.h"
@@ -852,25 +854,45 @@ TEST_P(DemanglingInfoCorrectnessTestFixutre, Correctness) {
852854

853855
auto tracked_name = llvm::StringRef(*OB);
854856

855-
auto return_left = tracked_name.slice(0, OB->NameInfo.ScopeRange.first);
856-
auto scope = tracked_name.slice(OB->NameInfo.ScopeRange.first,
857-
OB->NameInfo.ScopeRange.second);
858-
auto basename = tracked_name.slice(OB->NameInfo.BasenameRange.first,
859-
OB->NameInfo.BasenameRange.second);
860-
auto template_args = tracked_name.slice(OB->NameInfo.BasenameRange.second,
861-
OB->NameInfo.ArgumentsRange.first);
862-
auto args = tracked_name.slice(OB->NameInfo.ArgumentsRange.first,
863-
OB->NameInfo.ArgumentsRange.second);
864-
auto return_right = tracked_name.slice(OB->NameInfo.ArgumentsRange.second,
865-
OB->NameInfo.QualifiersRange.first);
866-
auto qualifiers = tracked_name.slice(OB->NameInfo.QualifiersRange.first,
867-
OB->NameInfo.QualifiersRange.second);
857+
std::string reconstructed_name;
858+
859+
auto return_left =
860+
CPlusPlusLanguage::GetDemangledReturnTypeLHS(tracked_name, OB->NameInfo);
861+
EXPECT_THAT_EXPECTED(return_left, llvm::Succeeded());
862+
reconstructed_name += *return_left;
863+
864+
auto scope = CPlusPlusLanguage::GetDemangledScope(tracked_name, OB->NameInfo);
865+
EXPECT_THAT_EXPECTED(scope, llvm::Succeeded());
866+
reconstructed_name += *scope;
867+
868+
auto basename =
869+
CPlusPlusLanguage::GetDemangledBasename(tracked_name, OB->NameInfo);
870+
reconstructed_name += basename;
871+
872+
auto template_args = CPlusPlusLanguage::GetDemangledTemplateArguments(
873+
tracked_name, OB->NameInfo);
874+
EXPECT_THAT_EXPECTED(template_args, llvm::Succeeded());
875+
reconstructed_name += *template_args;
876+
877+
auto args = CPlusPlusLanguage::GetDemangledFunctionArguments(tracked_name,
878+
OB->NameInfo);
879+
EXPECT_THAT_EXPECTED(args, llvm::Succeeded());
880+
reconstructed_name += *args;
881+
882+
auto return_right =
883+
CPlusPlusLanguage::GetDemangledReturnTypeRHS(tracked_name, OB->NameInfo);
884+
EXPECT_THAT_EXPECTED(return_right, llvm::Succeeded());
885+
reconstructed_name += *return_right;
886+
887+
auto qualifiers = CPlusPlusLanguage::GetDemangledFunctionQualifiers(
888+
tracked_name, OB->NameInfo);
889+
EXPECT_THAT_EXPECTED(qualifiers, llvm::Succeeded());
890+
reconstructed_name += *qualifiers;
891+
892+
// TODO: should retrieve suffix using the plugin too.
868893
auto suffix = tracked_name.slice(OB->NameInfo.QualifiersRange.second,
869894
llvm::StringRef::npos);
870-
871-
auto reconstructed_name =
872-
llvm::join_items("", return_left, scope, basename, template_args, args,
873-
return_right, qualifiers, suffix);
895+
reconstructed_name += suffix;
874896

875897
EXPECT_EQ(reconstructed_name, demangled);
876898
}

0 commit comments

Comments
 (0)