From 5bebc0b177d0f02af3d8d2b02d182c04763ee468 Mon Sep 17 00:00:00 2001 From: Alex Langford Date: Thu, 10 Jun 2021 14:55:25 -0700 Subject: [PATCH] [lldb] Decouple ObjCLanguage from Symtab We can extend/modify `GetMethodNameVariants` to suit our purposes here. What symtab is looking for is alternate names we may want to use to search for a specific symbol, and asking for variants of a name makes the most sense here. Differential Revision: https://reviews.llvm.org/D104067 --- lldb/include/lldb/Target/Language.h | 14 +++++++++-- lldb/source/Breakpoint/BreakpointResolverName.cpp | 14 +++++++---- lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp | 22 +++++++++++------ lldb/source/Plugins/Language/ObjC/ObjCLanguage.h | 3 ++- lldb/source/Symbol/CMakeLists.txt | 1 - lldb/source/Symbol/Symtab.cpp | 28 +++++++++++++++------- 6 files changed, 57 insertions(+), 25 deletions(-) diff --git a/lldb/include/lldb/Target/Language.h b/lldb/include/lldb/Target/Language.h index 0639a40..11b9daa 100644 --- a/lldb/include/lldb/Target/Language.h +++ b/lldb/include/lldb/Target/Language.h @@ -184,12 +184,22 @@ public: virtual const char *GetLanguageSpecificTypeLookupHelp(); + class MethodNameVariant { + ConstString m_name; + lldb::FunctionNameType m_type; + + public: + MethodNameVariant(ConstString name, lldb::FunctionNameType type) + : m_name(name), m_type(type) {} + ConstString GetName() const { return m_name; } + lldb::FunctionNameType GetType() const { return m_type; } + }; // If a language can have more than one possible name for a method, this // function can be used to enumerate them. This is useful when doing name // lookups. - virtual std::vector + virtual std::vector GetMethodNameVariants(ConstString method_name) const { - return std::vector(); + return std::vector(); }; /// Returns true iff the given symbol name is compatible with the mangling diff --git a/lldb/source/Breakpoint/BreakpointResolverName.cpp b/lldb/source/Breakpoint/BreakpointResolverName.cpp index b314135..121ac56 100644 --- a/lldb/source/Breakpoint/BreakpointResolverName.cpp +++ b/lldb/source/Breakpoint/BreakpointResolverName.cpp @@ -220,11 +220,15 @@ void BreakpointResolverName::AddNameLookup(ConstString name, m_lookups.emplace_back(lookup); auto add_variant_funcs = [&](Language *lang) { - for (ConstString variant_name : lang->GetMethodNameVariants(name)) { - Module::LookupInfo variant_lookup(name, name_type_mask, - lang->GetLanguageType()); - variant_lookup.SetLookupName(variant_name); - m_lookups.emplace_back(variant_lookup); + for (Language::MethodNameVariant variant : + lang->GetMethodNameVariants(name)) { + // FIXME: Should we be adding variants that aren't of type Full? + if (variant.GetType() & lldb::eFunctionNameTypeFull) { + Module::LookupInfo variant_lookup(name, variant.GetType(), + lang->GetLanguageType()); + variant_lookup.SetLookupName(variant.GetName()); + m_lookups.emplace_back(variant_lookup); + } } return true; }; diff --git a/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp b/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp index 785b1fd..3fb0c9e 100644 --- a/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp +++ b/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp @@ -225,14 +225,17 @@ ConstString ObjCLanguage::MethodName::GetFullNameWithoutCategory( return ConstString(); } -std::vector +std::vector ObjCLanguage::GetMethodNameVariants(ConstString method_name) const { - std::vector variant_names; + std::vector variant_names; ObjCLanguage::MethodName objc_method(method_name.GetCString(), false); if (!objc_method.IsValid(false)) { return variant_names; } + variant_names.emplace_back(objc_method.GetSelector(), + lldb::eFunctionNameTypeSelector); + const bool is_class_method = objc_method.GetType() == MethodName::eTypeClassMethod; const bool is_instance_method = @@ -242,25 +245,30 @@ ObjCLanguage::GetMethodNameVariants(ConstString method_name) const { if (is_class_method || is_instance_method) { if (name_sans_category) - variant_names.emplace_back(name_sans_category); + variant_names.emplace_back(name_sans_category, + lldb::eFunctionNameTypeFull); } else { StreamString strm; strm.Printf("+%s", objc_method.GetFullName().GetCString()); - variant_names.emplace_back(strm.GetString()); + variant_names.emplace_back(ConstString(strm.GetString()), + lldb::eFunctionNameTypeFull); strm.Clear(); strm.Printf("-%s", objc_method.GetFullName().GetCString()); - variant_names.emplace_back(strm.GetString()); + variant_names.emplace_back(ConstString(strm.GetString()), + lldb::eFunctionNameTypeFull); strm.Clear(); if (name_sans_category) { strm.Printf("+%s", name_sans_category.GetCString()); - variant_names.emplace_back(strm.GetString()); + variant_names.emplace_back(ConstString(strm.GetString()), + lldb::eFunctionNameTypeFull); strm.Clear(); strm.Printf("-%s", name_sans_category.GetCString()); - variant_names.emplace_back(strm.GetString()); + variant_names.emplace_back(ConstString(strm.GetString()), + lldb::eFunctionNameTypeFull); } } diff --git a/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h b/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h index 7401e54..691c518 100644 --- a/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h +++ b/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h @@ -100,7 +100,8 @@ public: // variant_names[1] => "-[NSString(my_additions) myStringWithCString:]" // variant_names[2] => "+[NSString myStringWithCString:]" // variant_names[3] => "-[NSString myStringWithCString:]" - std::vector + // Also returns the FunctionNameType of each possible name. + std::vector GetMethodNameVariants(ConstString method_name) const override; bool SymbolNameFitsToLanguage(Mangled mangled) const override; diff --git a/lldb/source/Symbol/CMakeLists.txt b/lldb/source/Symbol/CMakeLists.txt index 8ff874e..c983ceb 100644 --- a/lldb/source/Symbol/CMakeLists.txt +++ b/lldb/source/Symbol/CMakeLists.txt @@ -44,7 +44,6 @@ add_lldb_library(lldbSymbol lldbHost lldbTarget lldbUtility - lldbPluginObjCLanguage LINK_COMPONENTS Support diff --git a/lldb/source/Symbol/Symtab.cpp b/lldb/source/Symbol/Symtab.cpp index 18152d2..14360aa 100644 --- a/lldb/source/Symbol/Symtab.cpp +++ b/lldb/source/Symbol/Symtab.cpp @@ -9,8 +9,6 @@ #include #include -#include "Plugins/Language/ObjC/ObjCLanguage.h" - #include "lldb/Core/Module.h" #include "lldb/Core/RichManglingContext.h" #include "lldb/Core/Section.h" @@ -18,6 +16,7 @@ #include "lldb/Symbol/Symbol.h" #include "lldb/Symbol/SymbolContext.h" #include "lldb/Symbol/Symtab.h" +#include "lldb/Target/Language.h" #include "lldb/Utility/RegularExpression.h" #include "lldb/Utility/Stream.h" #include "lldb/Utility/Timer.h" @@ -268,6 +267,13 @@ void Symtab::InitNameIndexes() { m_name_indexes_computed = true; LLDB_SCOPED_TIMER(); + // Collect all loaded language plugins. + std::vector languages; + Language::ForEach([&languages](Language *l) { + languages.push_back(l); + return true; + }); + auto &name_to_index = GetNameToSymbolIndexMap(lldb::eFunctionNameTypeNone); auto &basename_to_index = GetNameToSymbolIndexMap(lldb::eFunctionNameTypeBase); @@ -334,13 +340,17 @@ void Symtab::InitNameIndexes() { // If the demangled name turns out to be an ObjC name, and is a category // name, add the version without categories to the index too. - ObjCLanguage::MethodName objc_method(name.GetStringRef(), true); - if (objc_method.IsValid(true)) { - selector_to_index.Append(objc_method.GetSelector(), value); - - if (ConstString objc_method_no_category = - objc_method.GetFullNameWithoutCategory(true)) - name_to_index.Append(objc_method_no_category, value); + for (Language *lang : languages) { + for (auto variant : lang->GetMethodNameVariants(name)) { + if (variant.GetType() & lldb::eFunctionNameTypeSelector) + selector_to_index.Append(variant.GetName(), value); + else if (variant.GetType() & lldb::eFunctionNameTypeFull) + name_to_index.Append(variant.GetName(), value); + else if (variant.GetType() & lldb::eFunctionNameTypeMethod) + method_to_index.Append(variant.GetName(), value); + else if (variant.GetType() & lldb::eFunctionNameTypeBase) + basename_to_index.Append(variant.GetName(), value); + } } } } -- 2.7.4