diff --git a/lldb/include/lldb/Target/Language.h b/lldb/include/lldb/Target/Language.h --- a/lldb/include/lldb/Target/Language.h +++ b/lldb/include/lldb/Target/Language.h @@ -293,6 +293,13 @@ 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 + GenerateAlternateFunctionManglings(const ConstString mangled) const { + return std::vector(); + } + protected: // Classes that inherit from Language can see and modify these diff --git a/lldb/source/Expression/IRExecutionUnit.cpp b/lldb/source/Expression/IRExecutionUnit.cpp --- a/lldb/source/Expression/IRExecutionUnit.cpp +++ b/lldb/source/Expression/IRExecutionUnit.cpp @@ -723,9 +723,11 @@ } } - std::set 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 alternates = + cpp_lang->GenerateAlternateFunctionManglings(name); + CPP_names.insert(CPP_names.end(), alternates.begin(), alternates.end()); + } } } diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h --- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h +++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h @@ -127,11 +127,8 @@ 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 &candidates); + std::vector + GenerateAlternateFunctionManglings(const ConstString mangled) const override; // PluginInterface protocol ConstString GetPluginName() override; diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp --- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp @@ -424,9 +424,10 @@ }; } // namespace -uint32_t CPlusPlusLanguage::FindAlternateFunctionManglings( - const ConstString mangled_name, std::set &alternates) { - const auto start_size = alternates.size(); +std::vector CPlusPlusLanguage::GenerateAlternateFunctionManglings( + const ConstString mangled_name) const { + std::vector 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 @@ 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 @@ 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 @@ // 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) { diff --git a/lldb/unittests/Language/CPlusPlus/CPlusPlusLanguageTest.cpp b/lldb/unittests/Language/CPlusPlus/CPlusPlusLanguageTest.cpp --- a/lldb/unittests/Language/CPlusPlus/CPlusPlusLanguageTest.cpp +++ b/lldb/unittests/Language/CPlusPlus/CPlusPlusLanguageTest.cpp @@ -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 @@ "operator<=>", context, basename)); } -static std::set FindAlternate(llvm::StringRef Name) { - std::set Results; - uint32_t Count = CPlusPlusLanguage::FindAlternateFunctionManglings( - ConstString(Name), Results); - EXPECT_EQ(Count, Results.size()); - std::set Strings; - for (ConstString Str : Results) - Strings.insert(std::string(Str.GetStringRef())); +static std::vector GenerateAlternate(llvm::StringRef Name) { + std::vector Strings; + if (Language *CPlusPlusLang = + Language::FindPlugin(lldb::eLanguageTypeC_plus_plus)) { + std::vector 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 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) {