Skip to content

Commit f669b9c

Browse files
authored
[lldb][test] Test all libcxxabi demangler test-cases against TrackingOutputBuffer (#137793)
To test the infrastructure added in #131836 in would be nice to confirm that we can reconstruct all kinds of demangled names. The libcxxabi test-suite already has all those test-cases. This patch copies those test-cases (taken from `libcxxabi/test/test_demangle.pass.cpp`), reconstructs the name like LLDB would when showing backtraces, and confirms that all demangled names can be fully reconstructed. Two open questions: 1. Do we really want a copy of all those test-cases in LLDB? It's unlikely to be kept in sync with the demangler test-suite. It includes 30,000+ test-cases 2. Do we want to turn the `GetDemangledBasename`/`GetDemangledScope`/etc. into public APIs (e.g., on `TrackingOutputBuffer`) so that we can use the exact same method of extraction in the tests?
1 parent c0b25f4 commit f669b9c

File tree

1 file changed

+63
-0
lines changed

1 file changed

+63
-0
lines changed

lldb/unittests/Core/MangledTest.cpp

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -612,3 +612,66 @@ TEST_P(DemanglingPartsTestFixture, DemanglingParts) {
612612

613613
INSTANTIATE_TEST_SUITE_P(DemanglingPartsTests, DemanglingPartsTestFixture,
614614
::testing::ValuesIn(g_demangling_parts_test_cases));
615+
616+
struct DemanglingInfoCorrectnessTestCase {
617+
const char *mangled;
618+
const char *demangled;
619+
};
620+
621+
DemanglingInfoCorrectnessTestCase g_demangling_correctness_test_cases[] = {
622+
#include "llvm/Testing/Demangle/DemangleTestCases.inc"
623+
};
624+
625+
struct DemanglingInfoCorrectnessTestFixutre
626+
: public ::testing::TestWithParam<DemanglingInfoCorrectnessTestCase> {};
627+
628+
TEST_P(DemanglingInfoCorrectnessTestFixutre, Correctness) {
629+
auto [mangled, demangled] = GetParam();
630+
631+
llvm::itanium_demangle::ManglingParser<TestAllocator> Parser(
632+
mangled, mangled + ::strlen(mangled));
633+
634+
const auto *Root = Parser.parse();
635+
636+
ASSERT_NE(nullptr, Root);
637+
638+
TrackingOutputBuffer OB;
639+
Root->print(OB);
640+
641+
// Filter out cases which would never show up in frames. We only care about
642+
// function names.
643+
if (Root->getKind() !=
644+
llvm::itanium_demangle::Node::Kind::KFunctionEncoding &&
645+
Root->getKind() != llvm::itanium_demangle::Node::Kind::KDotSuffix)
646+
return;
647+
648+
ASSERT_TRUE(OB.NameInfo.hasBasename());
649+
650+
auto tracked_name = llvm::StringRef(OB);
651+
652+
auto return_left = tracked_name.slice(0, OB.NameInfo.ScopeRange.first);
653+
auto scope = tracked_name.slice(OB.NameInfo.ScopeRange.first,
654+
OB.NameInfo.ScopeRange.second);
655+
auto basename = tracked_name.slice(OB.NameInfo.BasenameRange.first,
656+
OB.NameInfo.BasenameRange.second);
657+
auto template_args = tracked_name.slice(OB.NameInfo.BasenameRange.second,
658+
OB.NameInfo.ArgumentsRange.first);
659+
auto args = tracked_name.slice(OB.NameInfo.ArgumentsRange.first,
660+
OB.NameInfo.ArgumentsRange.second);
661+
auto return_right = tracked_name.slice(OB.NameInfo.ArgumentsRange.second,
662+
OB.NameInfo.QualifiersRange.first);
663+
auto qualifiers = tracked_name.slice(OB.NameInfo.QualifiersRange.first,
664+
OB.NameInfo.QualifiersRange.second);
665+
auto suffix = tracked_name.slice(OB.NameInfo.QualifiersRange.second,
666+
llvm::StringRef::npos);
667+
668+
auto reconstructed_name =
669+
llvm::join_items("", return_left, scope, basename, template_args, args,
670+
return_right, qualifiers, suffix);
671+
672+
EXPECT_EQ(reconstructed_name, demangled);
673+
}
674+
675+
INSTANTIATE_TEST_SUITE_P(
676+
DemanglingInfoCorrectnessTests, DemanglingInfoCorrectnessTestFixutre,
677+
::testing::ValuesIn(g_demangling_correctness_test_cases));

0 commit comments

Comments
 (0)