[lldb] Refactor and rename CPlusPlusLanguage::FindAlternateFunctionManglings

I have 2 goals with this change:
1. Disambiguate between CPlusPlus::FindAlternateFunctionManglings and
   IRExecutionUnit::FindBestAlternateMangledName. These are named very
   similar things, they try to do very similar things, but their
   approaches are different. This change should make it clear that one
   is generating possible alternate manglings (through some
   heuristics-based approach) and the other is finding alternate
   manglings (through searching the SymbolFile for potential matches).
2. Change GenerateAlternateFunctionManglings from a static method in
   CPlusPlusLanguage to a virtual method in Language. This will allow us
   to remove a direct use of CPlusPlusLanguage in IRExecutionUnit,
   further pushing it to be more general. This change doesn't meet this
   goal completely but allows for it to happen later.

Though this doesn't remove IRExecutionUnit's dependency on
CPlusPlusLanguage, it does bring us closer to that goal.

Differential Revision: https://reviews.llvm.org/D109785
This commit is contained in:
Alex Langford
2021-09-14 13:31:35 -07:00
parent 4c1023b4b7
commit a65f6aafe2
5 changed files with 47 additions and 35 deletions

View File

@@ -293,6 +293,13 @@ public:
static LanguageSet GetLanguagesSupportingTypeSystemsForExpressions();
static LanguageSet GetLanguagesSupportingREPLs();
// Given a mangled function name, calculates some alternative manglings since
// the compiler mangling may not line up with the symbol we are expecting.
virtual std::vector<ConstString>
GenerateAlternateFunctionManglings(const ConstString mangled) const {
return std::vector<ConstString>();
}
protected:
// Classes that inherit from Language can see and modify these

View File

@@ -723,9 +723,11 @@ void IRExecutionUnit::CollectCandidateCPlusPlusNames(
}
}
std::set<ConstString> alternates;
CPlusPlusLanguage::FindAlternateFunctionManglings(name, alternates);
CPP_names.insert(CPP_names.end(), alternates.begin(), alternates.end());
if (auto *cpp_lang = Language::FindPlugin(lldb::eLanguageTypeC_plus_plus)) {
std::vector<ConstString> alternates =
cpp_lang->GenerateAlternateFunctionManglings(name);
CPP_names.insert(CPP_names.end(), alternates.begin(), alternates.end());
}
}
}

View File

@@ -424,9 +424,10 @@ public:
};
} // namespace
uint32_t CPlusPlusLanguage::FindAlternateFunctionManglings(
const ConstString mangled_name, std::set<ConstString> &alternates) {
const auto start_size = alternates.size();
std::vector<ConstString> CPlusPlusLanguage::GenerateAlternateFunctionManglings(
const ConstString mangled_name) const {
std::vector<ConstString> alternates;
/// Get a basic set of alternative manglings for the given symbol `name`, by
/// making a few basic possible substitutions on basic types, storage duration
/// and `const`ness for the given symbol. The output parameter `alternates`
@@ -439,7 +440,7 @@ uint32_t CPlusPlusLanguage::FindAlternateFunctionManglings(
strncmp(mangled_name.GetCString(), "_ZNK", 4)) {
std::string fixed_scratch("_ZNK");
fixed_scratch.append(mangled_name.GetCString() + 3);
alternates.insert(ConstString(fixed_scratch));
alternates.push_back(ConstString(fixed_scratch));
}
// Maybe we're looking for a static symbol but we thought it was global...
@@ -447,7 +448,7 @@ uint32_t CPlusPlusLanguage::FindAlternateFunctionManglings(
strncmp(mangled_name.GetCString(), "_ZL", 3)) {
std::string fixed_scratch("_ZL");
fixed_scratch.append(mangled_name.GetCString() + 2);
alternates.insert(ConstString(fixed_scratch));
alternates.push_back(ConstString(fixed_scratch));
}
TypeSubstitutor TS;
@@ -457,24 +458,24 @@ uint32_t CPlusPlusLanguage::FindAlternateFunctionManglings(
// parameter, try finding matches which have the general case 'c'.
if (ConstString char_fixup =
TS.substitute(mangled_name.GetStringRef(), "a", "c"))
alternates.insert(char_fixup);
alternates.push_back(char_fixup);
// long long parameter mangling 'x', may actually just be a long 'l' argument
if (ConstString long_fixup =
TS.substitute(mangled_name.GetStringRef(), "x", "l"))
alternates.insert(long_fixup);
alternates.push_back(long_fixup);
// unsigned long long parameter mangling 'y', may actually just be unsigned
// long 'm' argument
if (ConstString ulong_fixup =
TS.substitute(mangled_name.GetStringRef(), "y", "m"))
alternates.insert(ulong_fixup);
alternates.push_back(ulong_fixup);
if (ConstString ctor_fixup =
CtorDtorSubstitutor().substitute(mangled_name.GetStringRef()))
alternates.insert(ctor_fixup);
alternates.push_back(ctor_fixup);
return alternates.size() - start_size;
return alternates;
}
static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {

View File

@@ -127,11 +127,8 @@ public:
llvm::StringRef &context,
llvm::StringRef &identifier);
// Given a mangled function name, calculates some alternative manglings since
// the compiler mangling may not line up with the symbol we are expecting
static uint32_t
FindAlternateFunctionManglings(const ConstString mangled,
std::set<ConstString> &candidates);
std::vector<ConstString>
GenerateAlternateFunctionManglings(const ConstString mangled) const override;
// PluginInterface protocol
ConstString GetPluginName() override;

View File

@@ -7,6 +7,8 @@
//===----------------------------------------------------------------------===//
#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
#include "Plugins/Language/CPlusPlus/CPlusPlusNameParser.h"
#include "TestingSupport/SubsystemRAII.h"
#include "lldb/lldb-enumerations.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
@@ -185,29 +187,32 @@ TEST(CPlusPlusLanguage, ExtractContextAndIdentifier) {
"operator<=><A::B>", context, basename));
}
static std::set<std::string> FindAlternate(llvm::StringRef Name) {
std::set<ConstString> Results;
uint32_t Count = CPlusPlusLanguage::FindAlternateFunctionManglings(
ConstString(Name), Results);
EXPECT_EQ(Count, Results.size());
std::set<std::string> Strings;
for (ConstString Str : Results)
Strings.insert(std::string(Str.GetStringRef()));
static std::vector<std::string> GenerateAlternate(llvm::StringRef Name) {
std::vector<std::string> Strings;
if (Language *CPlusPlusLang =
Language::FindPlugin(lldb::eLanguageTypeC_plus_plus)) {
std::vector<ConstString> Results =
CPlusPlusLang->GenerateAlternateFunctionManglings(ConstString(Name));
for (ConstString Str : Results)
Strings.push_back(std::string(Str.GetStringRef()));
}
return Strings;
}
TEST(CPlusPlusLanguage, FindAlternateFunctionManglings) {
TEST(CPlusPlusLanguage, GenerateAlternateFunctionManglings) {
using namespace testing;
EXPECT_THAT(FindAlternate("_ZN1A1fEv"),
SubsystemRAII<CPlusPlusLanguage> lang;
EXPECT_THAT(GenerateAlternate("_ZN1A1fEv"),
UnorderedElementsAre("_ZNK1A1fEv", "_ZLN1A1fEv"));
EXPECT_THAT(FindAlternate("_ZN1A1fEa"), Contains("_ZN1A1fEc"));
EXPECT_THAT(FindAlternate("_ZN1A1fEx"), Contains("_ZN1A1fEl"));
EXPECT_THAT(FindAlternate("_ZN1A1fEy"), Contains("_ZN1A1fEm"));
EXPECT_THAT(FindAlternate("_ZN1A1fEai"), Contains("_ZN1A1fEci"));
EXPECT_THAT(FindAlternate("_ZN1AC1Ev"), Contains("_ZN1AC2Ev"));
EXPECT_THAT(FindAlternate("_ZN1AD1Ev"), Contains("_ZN1AD2Ev"));
EXPECT_THAT(FindAlternate("_bogus"), IsEmpty());
EXPECT_THAT(GenerateAlternate("_ZN1A1fEa"), Contains("_ZN1A1fEc"));
EXPECT_THAT(GenerateAlternate("_ZN1A1fEx"), Contains("_ZN1A1fEl"));
EXPECT_THAT(GenerateAlternate("_ZN1A1fEy"), Contains("_ZN1A1fEm"));
EXPECT_THAT(GenerateAlternate("_ZN1A1fEai"), Contains("_ZN1A1fEci"));
EXPECT_THAT(GenerateAlternate("_ZN1AC1Ev"), Contains("_ZN1AC2Ev"));
EXPECT_THAT(GenerateAlternate("_ZN1AD1Ev"), Contains("_ZN1AD2Ev"));
EXPECT_THAT(GenerateAlternate("_bogus"), IsEmpty());
}
TEST(CPlusPlusLanguage, CPlusPlusNameParser) {