[Lldb-commits] [lldb] cd2134e - [lldb] Refactor Module::LookupInfo constructor

Alex Langford via lldb-commits lldb-commits at lists.llvm.org
Tue Aug 24 13:54:00 PDT 2021


Author: Alex Langford
Date: 2021-08-24T13:53:49-07:00
New Revision: cd2134e42aa7d1168a3ed54e41793b022f961b1f

URL: https://github.com/llvm/llvm-project/commit/cd2134e42aa7d1168a3ed54e41793b022f961b1f
DIFF: https://github.com/llvm/llvm-project/commit/cd2134e42aa7d1168a3ed54e41793b022f961b1f.diff

LOG: [lldb] Refactor Module::LookupInfo constructor

Module::LookupInfo's constructor currently goes over supported languages
trying to figure out the best way to search for a symbol name. This
seems like a great candidate for refactoring. Specifically, this is work
that can be delegated to language plugins.

Once again, the goal here is to further decouple plugins from
non-plugins. The idea is to have each language plugin take a name and
give you back some information about the name from the perspective of
the language. Specifically, each language now implements a
`GetFunctionNameInfo` method which returns an object of type
`Language::FunctionNameInfo`. Right now, it consists of a basename,
a context, and a FunctionNameType. Module::LookupInfo's constructor will
call `GetFunctionNameInfo` with the appropriate language plugin(s) and
then decide what to do with that information. I have attempted to maintain
existing behavior as best as possible.

A nice side effect of this change is that lldbCore no longer links
against the ObjC Language plugin.

Differential Revision: https://reviews.llvm.org/D108229

Added: 
    

Modified: 
    lldb/include/lldb/Core/Module.h
    lldb/include/lldb/Target/Language.h
    lldb/source/Core/CMakeLists.txt
    lldb/source/Core/Module.cpp
    lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
    lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
    lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp
    lldb/source/Plugins/Language/ObjC/ObjCLanguage.h

Removed: 
    


################################################################################
diff  --git a/lldb/include/lldb/Core/Module.h b/lldb/include/lldb/Core/Module.h
index 767f2d232947c..07f75191ca74d 100644
--- a/lldb/include/lldb/Core/Module.h
+++ b/lldb/include/lldb/Core/Module.h
@@ -896,7 +896,7 @@ class Module : public std::enable_shared_from_this<Module>,
     LookupInfo() : m_name(), m_lookup_name() {}
 
     LookupInfo(ConstString name, lldb::FunctionNameType name_type_mask,
-               lldb::LanguageType language);
+               lldb::LanguageType language_type);
 
     ConstString GetName() const { return m_name; }
 
@@ -922,7 +922,7 @@ class Module : public std::enable_shared_from_this<Module>,
     ConstString m_lookup_name;
 
     /// Limit matches to only be for this language
-    lldb::LanguageType m_language = lldb::eLanguageTypeUnknown;
+    lldb::LanguageType m_language_type = lldb::eLanguageTypeUnknown;
 
     /// One or more bits from lldb::FunctionNameType that indicate what kind of
     /// names we are looking for

diff  --git a/lldb/include/lldb/Target/Language.h b/lldb/include/lldb/Target/Language.h
index 2ad9677ea3f8c..73cba0726be64 100644
--- a/lldb/include/lldb/Target/Language.h
+++ b/lldb/include/lldb/Target/Language.h
@@ -202,6 +202,20 @@ class Language : public PluginInterface {
     return std::vector<Language::MethodNameVariant>();
   };
 
+  class FunctionNameInfo {
+  public:
+    llvm::StringRef basename;
+    llvm::StringRef context;
+    lldb::FunctionNameType func_name_type;
+  };
+
+  virtual Language::FunctionNameInfo
+  GetFunctionNameInfo(ConstString name) const {
+    FunctionNameInfo ret;
+    ret.func_name_type = lldb::eFunctionNameTypeNone;
+    return ret;
+  };
+
   /// Returns true iff the given symbol name is compatible with the mangling
   /// scheme of this language.
   ///

diff  --git a/lldb/source/Core/CMakeLists.txt b/lldb/source/Core/CMakeLists.txt
index 65be803addf5f..2257b883fc403 100644
--- a/lldb/source/Core/CMakeLists.txt
+++ b/lldb/source/Core/CMakeLists.txt
@@ -82,7 +82,6 @@ add_lldb_library(lldbCore
     lldbTarget
     lldbUtility
     lldbPluginCPlusPlusLanguage
-    lldbPluginObjCLanguage
     ${LLDB_CURSES_LIBS}
 
   CLANG_LIBS

diff  --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp
index c7538db7dd240..16308d9dd0b88 100644
--- a/lldb/source/Core/Module.cpp
+++ b/lldb/source/Core/Module.cpp
@@ -51,7 +51,6 @@
 #endif
 
 #include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
-#include "Plugins/Language/ObjC/ObjCLanguage.h"
 
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/Support/Compiler.h"
@@ -635,101 +634,81 @@ void Module::FindCompileUnits(const FileSpec &path,
 
 Module::LookupInfo::LookupInfo(ConstString name,
                                FunctionNameType name_type_mask,
-                               LanguageType language)
-    : m_name(name), m_lookup_name(), m_language(language),
+                               LanguageType language_type)
+    : m_name(name), m_lookup_name(name), m_language_type(language_type),
       m_name_type_mask(eFunctionNameTypeNone),
       m_match_name_after_lookup(false) {
-  const char *name_cstr = name.GetCString();
   llvm::StringRef basename;
   llvm::StringRef context;
 
+  std::vector<Language *> languages;
+  Language::ForEach([&languages](Language *l) {
+    languages.push_back(l);
+    return true;
+  });
+
   if (name_type_mask & eFunctionNameTypeAuto) {
-    if (CPlusPlusLanguage::IsCPPMangledName(name_cstr))
-      m_name_type_mask = eFunctionNameTypeFull;
-    else if ((language == eLanguageTypeUnknown ||
-              Language::LanguageIsObjC(language)) &&
-             ObjCLanguage::IsPossibleObjCMethodName(name_cstr))
-      m_name_type_mask = eFunctionNameTypeFull;
-    else if (Language::LanguageIsC(language)) {
-      m_name_type_mask = eFunctionNameTypeFull;
+    if (language_type == eLanguageTypeUnknown) {
+      for (Language *lang : languages) {
+        Language::FunctionNameInfo info = lang->GetFunctionNameInfo(name);
+        if (info.func_name_type != eFunctionNameTypeNone) {
+          m_name_type_mask = info.func_name_type;
+          basename = info.basename;
+          context = info.context;
+          break;
+        }
+      }
     } else {
-      if ((language == eLanguageTypeUnknown ||
-           Language::LanguageIsObjC(language)) &&
-          ObjCLanguage::IsPossibleObjCSelector(name_cstr))
-        m_name_type_mask |= eFunctionNameTypeSelector;
-
-      CPlusPlusLanguage::MethodName cpp_method(name);
-      basename = cpp_method.GetBasename();
-      if (basename.empty()) {
-        if (CPlusPlusLanguage::ExtractContextAndIdentifier(name_cstr, context,
-                                                           basename))
-          m_name_type_mask |= (eFunctionNameTypeMethod | eFunctionNameTypeBase);
-        else
-          m_name_type_mask |= eFunctionNameTypeFull;
-      } else {
-        m_name_type_mask |= (eFunctionNameTypeMethod | eFunctionNameTypeBase);
+      if (auto *lang = Language::FindPlugin(language_type)) {
+        Language::FunctionNameInfo info = lang->GetFunctionNameInfo(name);
+        m_name_type_mask = info.func_name_type;
+        basename = info.basename;
+        context = info.context;
       }
     }
+
+    // NOTE: There are several ways to get here, but this is a fallback path in
+    // case the above does not succeed at extracting any useful information from
+    // the loaded language plugins.
+    if (m_name_type_mask == eFunctionNameTypeNone)
+      m_name_type_mask = eFunctionNameTypeFull;
+
   } else {
     m_name_type_mask = name_type_mask;
-    if (name_type_mask & eFunctionNameTypeMethod ||
-        name_type_mask & eFunctionNameTypeBase) {
-      // If they've asked for a CPP method or function name and it can't be
-      // that, we don't even need to search for CPP methods or names.
-      CPlusPlusLanguage::MethodName cpp_method(name);
-      if (cpp_method.IsValid()) {
-        basename = cpp_method.GetBasename();
-
-        if (!cpp_method.GetQualifiers().empty()) {
-          // There is a "const" or other qualifier following the end of the
-          // function parens, this can't be a eFunctionNameTypeBase
-          m_name_type_mask &= ~(eFunctionNameTypeBase);
-          if (m_name_type_mask == eFunctionNameTypeNone)
-            return;
+    if (language_type != eLanguageTypeUnknown) {
+      if (auto *lang = Language::FindPlugin(language_type)) {
+        Language::FunctionNameInfo info = lang->GetFunctionNameInfo(name);
+        if (info.func_name_type & m_name_type_mask) {
+          // If the user asked for FunctionNameTypes that aren't possible,
+          // then filter those out. (e.g. asking for Selectors on
+          // C++ symbols, or even if the symbol given can't be a selector in
+          // ObjC)
+          m_name_type_mask &= info.func_name_type;
+          basename = info.basename;
+          context = info.context;
         }
-      } else {
-        // If the CPP method parser didn't manage to chop this up, try to fill
-        // in the base name if we can. If a::b::c is passed in, we need to just
-        // look up "c", and then we'll filter the result later.
-        CPlusPlusLanguage::ExtractContextAndIdentifier(name_cstr, context,
-                                                       basename);
-      }
-    }
-
-    if (name_type_mask & eFunctionNameTypeSelector) {
-      if (!ObjCLanguage::IsPossibleObjCSelector(name_cstr)) {
-        m_name_type_mask &= ~(eFunctionNameTypeSelector);
-        if (m_name_type_mask == eFunctionNameTypeNone)
-          return;
       }
-    }
-
-    // Still try and get a basename in case someone specifies a name type mask
-    // of eFunctionNameTypeFull and a name like "A::func"
-    if (basename.empty()) {
-      if (name_type_mask & eFunctionNameTypeFull &&
-          !CPlusPlusLanguage::IsCPPMangledName(name_cstr)) {
-        CPlusPlusLanguage::MethodName cpp_method(name);
-        basename = cpp_method.GetBasename();
-        if (basename.empty())
-          CPlusPlusLanguage::ExtractContextAndIdentifier(name_cstr, context,
-                                                         basename);
+    } else {
+      for (Language *lang : languages) {
+        Language::FunctionNameInfo info = lang->GetFunctionNameInfo(name);
+        if (info.func_name_type & m_name_type_mask) {
+          m_name_type_mask &= info.func_name_type;
+          basename = info.basename;
+          context = info.context;
+          break;
+        }
       }
     }
   }
 
   if (!basename.empty()) {
-    // The name supplied was a partial C++ path like "a::count". In this case
-    // we want to do a lookup on the basename "count" and then make sure any
-    // matching results contain "a::count" so that it would match "b::a::count"
-    // and "a::count". This is why we set "match_name_after_lookup" to true
+    // The name supplied was incomplete for lookup purposes. For example, in C++
+    // we may have gotten something like "a::count". In this case, we want to do
+    // a lookup on the basename "count" and then make sure any matching results
+    // contain "a::count" so that it would match "b::a::count" and "a::count".
+    // This is why we set match_name_after_lookup to true.
     m_lookup_name.SetString(basename);
     m_match_name_after_lookup = true;
-  } else {
-    // The name is already correct, just use the exact name as supplied, and we
-    // won't need to check if any matches contain "name"
-    m_lookup_name = name;
-    m_match_name_after_lookup = false;
   }
 }
 

diff  --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index 814bfe28ca31a..3e57951471c46 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -59,6 +59,39 @@ lldb_private::ConstString CPlusPlusLanguage::GetPluginNameStatic() {
   return g_name;
 }
 
+Language::FunctionNameInfo
+CPlusPlusLanguage::GetFunctionNameInfo(ConstString name) const {
+  FunctionNameInfo info;
+  info.func_name_type = lldb::eFunctionNameTypeNone;
+
+  if (IsCPPMangledName(name.GetCString())) {
+    info.func_name_type = lldb::eFunctionNameTypeFull;
+  }
+
+  CPlusPlusLanguage::MethodName method(name);
+  llvm::StringRef basename = method.GetBasename();
+  if (basename.empty()) {
+    if (CPlusPlusLanguage::ExtractContextAndIdentifier(
+            name.GetCString(), info.context, info.basename)) {
+      info.func_name_type |=
+          (lldb::eFunctionNameTypeMethod | eFunctionNameTypeBase);
+    } else {
+      info.func_name_type |= lldb::eFunctionNameTypeFull;
+    }
+  } else {
+    info.func_name_type |=
+        (lldb::eFunctionNameTypeMethod | eFunctionNameTypeBase);
+  }
+
+  if (!method.GetQualifiers().empty()) {
+    // There is a 'const' or other qualifier following the end of the function
+    // parens, this can't be a eFunctionNameTypeBase.
+    info.func_name_type &= ~(lldb::eFunctionNameTypeBase);
+  }
+
+  return info;
+}
+
 bool CPlusPlusLanguage::SymbolNameFitsToLanguage(Mangled mangled) const {
   const char *mangled_name = mangled.GetMangledName().GetCString();
   return mangled_name && CPlusPlusLanguage::IsCPPMangledName(mangled_name);

diff  --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
index 46d708bec192a..985820d24d8a5 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
+++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
@@ -104,6 +104,9 @@ class CPlusPlusLanguage : public Language {
 
   static lldb_private::ConstString GetPluginNameStatic();
 
+  Language::FunctionNameInfo
+  GetFunctionNameInfo(ConstString name) const override;
+
   bool SymbolNameFitsToLanguage(Mangled mangled) const override;
 
   ConstString

diff  --git a/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp b/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp
index 613b2fb2d8a5a..46cf5ce3910cd 100644
--- a/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp
+++ b/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp
@@ -275,6 +275,22 @@ ObjCLanguage::GetMethodNameVariants(ConstString method_name) const {
   return variant_names;
 }
 
+Language::FunctionNameInfo
+ObjCLanguage::GetFunctionNameInfo(ConstString name) const {
+  Language::FunctionNameInfo info;
+  info.func_name_type = lldb::eFunctionNameTypeNone;
+
+  if (ObjCLanguage::IsPossibleObjCMethodName(name.GetCString())) {
+    info.func_name_type = lldb::eFunctionNameTypeFull;
+  }
+
+  if (ObjCLanguage::IsPossibleObjCSelector(name.GetCString())) {
+    info.func_name_type |= lldb::eFunctionNameTypeSelector;
+  }
+
+  return info;
+}
+
 bool ObjCLanguage::SymbolNameFitsToLanguage(Mangled mangled) const {
   ConstString demangled_name = mangled.GetDemangledName();
   if (!demangled_name)

diff  --git a/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h b/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h
index 691c51883c8a3..38a5572900989 100644
--- a/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h
+++ b/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h
@@ -104,6 +104,9 @@ class ObjCLanguage : public Language {
   std::vector<Language::MethodNameVariant>
   GetMethodNameVariants(ConstString method_name) const override;
 
+  Language::FunctionNameInfo
+  GetFunctionNameInfo(ConstString name) const override;
+
   bool SymbolNameFitsToLanguage(Mangled mangled) const override;
 
   lldb::TypeCategoryImplSP GetFormatters() override;


        


More information about the lldb-commits mailing list