[lldb] Refactor and rename CPlusPlusLanguage::FindAlternateFunctionManglings
authorAlex Langford <apl@fb.com>
Tue, 14 Sep 2021 20:31:35 +0000 (13:31 -0700)
committerAlex Langford <apl@fb.com>
Thu, 16 Sep 2021 20:13:07 +0000 (13:13 -0700)
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

lldb/include/lldb/Target/Language.h
lldb/source/Expression/IRExecutionUnit.cpp
lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
lldb/unittests/Language/CPlusPlus/CPlusPlusLanguageTest.cpp

index 2ad9677..41a0a5e 100644 (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
 
index 5c58ee6..4306a9c 100644 (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());
+    }
   }
 }
 
index 0a4d4fb..c839a3d 100644 (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) {
index 1939f43..df8172a 100644 (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;
index e8e6a4c..20abd5a 100644 (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) {