Skip to content

Commit cd2134e

Browse files
committed
[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
1 parent 9d2740f commit cd2134e

File tree

8 files changed

+126
-79
lines changed

8 files changed

+126
-79
lines changed

lldb/include/lldb/Core/Module.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -896,7 +896,7 @@ class Module : public std::enable_shared_from_this<Module>,
896896
LookupInfo() : m_name(), m_lookup_name() {}
897897

898898
LookupInfo(ConstString name, lldb::FunctionNameType name_type_mask,
899-
lldb::LanguageType language);
899+
lldb::LanguageType language_type);
900900

901901
ConstString GetName() const { return m_name; }
902902

@@ -922,7 +922,7 @@ class Module : public std::enable_shared_from_this<Module>,
922922
ConstString m_lookup_name;
923923

924924
/// Limit matches to only be for this language
925-
lldb::LanguageType m_language = lldb::eLanguageTypeUnknown;
925+
lldb::LanguageType m_language_type = lldb::eLanguageTypeUnknown;
926926

927927
/// One or more bits from lldb::FunctionNameType that indicate what kind of
928928
/// names we are looking for

lldb/include/lldb/Target/Language.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,20 @@ class Language : public PluginInterface {
202202
return std::vector<Language::MethodNameVariant>();
203203
};
204204

205+
class FunctionNameInfo {
206+
public:
207+
llvm::StringRef basename;
208+
llvm::StringRef context;
209+
lldb::FunctionNameType func_name_type;
210+
};
211+
212+
virtual Language::FunctionNameInfo
213+
GetFunctionNameInfo(ConstString name) const {
214+
FunctionNameInfo ret;
215+
ret.func_name_type = lldb::eFunctionNameTypeNone;
216+
return ret;
217+
};
218+
205219
/// Returns true iff the given symbol name is compatible with the mangling
206220
/// scheme of this language.
207221
///

lldb/source/Core/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,6 @@ add_lldb_library(lldbCore
8282
lldbTarget
8383
lldbUtility
8484
lldbPluginCPlusPlusLanguage
85-
lldbPluginObjCLanguage
8685
${LLDB_CURSES_LIBS}
8786

8887
CLANG_LIBS

lldb/source/Core/Module.cpp

Lines changed: 55 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@
5151
#endif
5252

5353
#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
54-
#include "Plugins/Language/ObjC/ObjCLanguage.h"
5554

5655
#include "llvm/ADT/STLExtras.h"
5756
#include "llvm/Support/Compiler.h"
@@ -635,101 +634,81 @@ void Module::FindCompileUnits(const FileSpec &path,
635634

636635
Module::LookupInfo::LookupInfo(ConstString name,
637636
FunctionNameType name_type_mask,
638-
LanguageType language)
639-
: m_name(name), m_lookup_name(), m_language(language),
637+
LanguageType language_type)
638+
: m_name(name), m_lookup_name(name), m_language_type(language_type),
640639
m_name_type_mask(eFunctionNameTypeNone),
641640
m_match_name_after_lookup(false) {
642-
const char *name_cstr = name.GetCString();
643641
llvm::StringRef basename;
644642
llvm::StringRef context;
645643

644+
std::vector<Language *> languages;
645+
Language::ForEach([&languages](Language *l) {
646+
languages.push_back(l);
647+
return true;
648+
});
649+
646650
if (name_type_mask & eFunctionNameTypeAuto) {
647-
if (CPlusPlusLanguage::IsCPPMangledName(name_cstr))
648-
m_name_type_mask = eFunctionNameTypeFull;
649-
else if ((language == eLanguageTypeUnknown ||
650-
Language::LanguageIsObjC(language)) &&
651-
ObjCLanguage::IsPossibleObjCMethodName(name_cstr))
652-
m_name_type_mask = eFunctionNameTypeFull;
653-
else if (Language::LanguageIsC(language)) {
654-
m_name_type_mask = eFunctionNameTypeFull;
651+
if (language_type == eLanguageTypeUnknown) {
652+
for (Language *lang : languages) {
653+
Language::FunctionNameInfo info = lang->GetFunctionNameInfo(name);
654+
if (info.func_name_type != eFunctionNameTypeNone) {
655+
m_name_type_mask = info.func_name_type;
656+
basename = info.basename;
657+
context = info.context;
658+
break;
659+
}
660+
}
655661
} else {
656-
if ((language == eLanguageTypeUnknown ||
657-
Language::LanguageIsObjC(language)) &&
658-
ObjCLanguage::IsPossibleObjCSelector(name_cstr))
659-
m_name_type_mask |= eFunctionNameTypeSelector;
660-
661-
CPlusPlusLanguage::MethodName cpp_method(name);
662-
basename = cpp_method.GetBasename();
663-
if (basename.empty()) {
664-
if (CPlusPlusLanguage::ExtractContextAndIdentifier(name_cstr, context,
665-
basename))
666-
m_name_type_mask |= (eFunctionNameTypeMethod | eFunctionNameTypeBase);
667-
else
668-
m_name_type_mask |= eFunctionNameTypeFull;
669-
} else {
670-
m_name_type_mask |= (eFunctionNameTypeMethod | eFunctionNameTypeBase);
662+
if (auto *lang = Language::FindPlugin(language_type)) {
663+
Language::FunctionNameInfo info = lang->GetFunctionNameInfo(name);
664+
m_name_type_mask = info.func_name_type;
665+
basename = info.basename;
666+
context = info.context;
671667
}
672668
}
669+
670+
// NOTE: There are several ways to get here, but this is a fallback path in
671+
// case the above does not succeed at extracting any useful information from
672+
// the loaded language plugins.
673+
if (m_name_type_mask == eFunctionNameTypeNone)
674+
m_name_type_mask = eFunctionNameTypeFull;
675+
673676
} else {
674677
m_name_type_mask = name_type_mask;
675-
if (name_type_mask & eFunctionNameTypeMethod ||
676-
name_type_mask & eFunctionNameTypeBase) {
677-
// If they've asked for a CPP method or function name and it can't be
678-
// that, we don't even need to search for CPP methods or names.
679-
CPlusPlusLanguage::MethodName cpp_method(name);
680-
if (cpp_method.IsValid()) {
681-
basename = cpp_method.GetBasename();
682-
683-
if (!cpp_method.GetQualifiers().empty()) {
684-
// There is a "const" or other qualifier following the end of the
685-
// function parens, this can't be a eFunctionNameTypeBase
686-
m_name_type_mask &= ~(eFunctionNameTypeBase);
687-
if (m_name_type_mask == eFunctionNameTypeNone)
688-
return;
678+
if (language_type != eLanguageTypeUnknown) {
679+
if (auto *lang = Language::FindPlugin(language_type)) {
680+
Language::FunctionNameInfo info = lang->GetFunctionNameInfo(name);
681+
if (info.func_name_type & m_name_type_mask) {
682+
// If the user asked for FunctionNameTypes that aren't possible,
683+
// then filter those out. (e.g. asking for Selectors on
684+
// C++ symbols, or even if the symbol given can't be a selector in
685+
// ObjC)
686+
m_name_type_mask &= info.func_name_type;
687+
basename = info.basename;
688+
context = info.context;
689689
}
690-
} else {
691-
// If the CPP method parser didn't manage to chop this up, try to fill
692-
// in the base name if we can. If a::b::c is passed in, we need to just
693-
// look up "c", and then we'll filter the result later.
694-
CPlusPlusLanguage::ExtractContextAndIdentifier(name_cstr, context,
695-
basename);
696-
}
697-
}
698-
699-
if (name_type_mask & eFunctionNameTypeSelector) {
700-
if (!ObjCLanguage::IsPossibleObjCSelector(name_cstr)) {
701-
m_name_type_mask &= ~(eFunctionNameTypeSelector);
702-
if (m_name_type_mask == eFunctionNameTypeNone)
703-
return;
704690
}
705-
}
706-
707-
// Still try and get a basename in case someone specifies a name type mask
708-
// of eFunctionNameTypeFull and a name like "A::func"
709-
if (basename.empty()) {
710-
if (name_type_mask & eFunctionNameTypeFull &&
711-
!CPlusPlusLanguage::IsCPPMangledName(name_cstr)) {
712-
CPlusPlusLanguage::MethodName cpp_method(name);
713-
basename = cpp_method.GetBasename();
714-
if (basename.empty())
715-
CPlusPlusLanguage::ExtractContextAndIdentifier(name_cstr, context,
716-
basename);
691+
} else {
692+
for (Language *lang : languages) {
693+
Language::FunctionNameInfo info = lang->GetFunctionNameInfo(name);
694+
if (info.func_name_type & m_name_type_mask) {
695+
m_name_type_mask &= info.func_name_type;
696+
basename = info.basename;
697+
context = info.context;
698+
break;
699+
}
717700
}
718701
}
719702
}
720703

721704
if (!basename.empty()) {
722-
// The name supplied was a partial C++ path like "a::count". In this case
723-
// we want to do a lookup on the basename "count" and then make sure any
724-
// matching results contain "a::count" so that it would match "b::a::count"
725-
// and "a::count". This is why we set "match_name_after_lookup" to true
705+
// The name supplied was incomplete for lookup purposes. For example, in C++
706+
// we may have gotten something like "a::count". In this case, we want to do
707+
// a lookup on the basename "count" and then make sure any matching results
708+
// contain "a::count" so that it would match "b::a::count" and "a::count".
709+
// This is why we set match_name_after_lookup to true.
726710
m_lookup_name.SetString(basename);
727711
m_match_name_after_lookup = true;
728-
} else {
729-
// The name is already correct, just use the exact name as supplied, and we
730-
// won't need to check if any matches contain "name"
731-
m_lookup_name = name;
732-
m_match_name_after_lookup = false;
733712
}
734713
}
735714

lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,39 @@ lldb_private::ConstString CPlusPlusLanguage::GetPluginNameStatic() {
5959
return g_name;
6060
}
6161

62+
Language::FunctionNameInfo
63+
CPlusPlusLanguage::GetFunctionNameInfo(ConstString name) const {
64+
FunctionNameInfo info;
65+
info.func_name_type = lldb::eFunctionNameTypeNone;
66+
67+
if (IsCPPMangledName(name.GetCString())) {
68+
info.func_name_type = lldb::eFunctionNameTypeFull;
69+
}
70+
71+
CPlusPlusLanguage::MethodName method(name);
72+
llvm::StringRef basename = method.GetBasename();
73+
if (basename.empty()) {
74+
if (CPlusPlusLanguage::ExtractContextAndIdentifier(
75+
name.GetCString(), info.context, info.basename)) {
76+
info.func_name_type |=
77+
(lldb::eFunctionNameTypeMethod | eFunctionNameTypeBase);
78+
} else {
79+
info.func_name_type |= lldb::eFunctionNameTypeFull;
80+
}
81+
} else {
82+
info.func_name_type |=
83+
(lldb::eFunctionNameTypeMethod | eFunctionNameTypeBase);
84+
}
85+
86+
if (!method.GetQualifiers().empty()) {
87+
// There is a 'const' or other qualifier following the end of the function
88+
// parens, this can't be a eFunctionNameTypeBase.
89+
info.func_name_type &= ~(lldb::eFunctionNameTypeBase);
90+
}
91+
92+
return info;
93+
}
94+
6295
bool CPlusPlusLanguage::SymbolNameFitsToLanguage(Mangled mangled) const {
6396
const char *mangled_name = mangled.GetMangledName().GetCString();
6497
return mangled_name && CPlusPlusLanguage::IsCPPMangledName(mangled_name);

lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,9 @@ class CPlusPlusLanguage : public Language {
104104

105105
static lldb_private::ConstString GetPluginNameStatic();
106106

107+
Language::FunctionNameInfo
108+
GetFunctionNameInfo(ConstString name) const override;
109+
107110
bool SymbolNameFitsToLanguage(Mangled mangled) const override;
108111

109112
ConstString

lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,22 @@ ObjCLanguage::GetMethodNameVariants(ConstString method_name) const {
275275
return variant_names;
276276
}
277277

278+
Language::FunctionNameInfo
279+
ObjCLanguage::GetFunctionNameInfo(ConstString name) const {
280+
Language::FunctionNameInfo info;
281+
info.func_name_type = lldb::eFunctionNameTypeNone;
282+
283+
if (ObjCLanguage::IsPossibleObjCMethodName(name.GetCString())) {
284+
info.func_name_type = lldb::eFunctionNameTypeFull;
285+
}
286+
287+
if (ObjCLanguage::IsPossibleObjCSelector(name.GetCString())) {
288+
info.func_name_type |= lldb::eFunctionNameTypeSelector;
289+
}
290+
291+
return info;
292+
}
293+
278294
bool ObjCLanguage::SymbolNameFitsToLanguage(Mangled mangled) const {
279295
ConstString demangled_name = mangled.GetDemangledName();
280296
if (!demangled_name)

lldb/source/Plugins/Language/ObjC/ObjCLanguage.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,9 @@ class ObjCLanguage : public Language {
104104
std::vector<Language::MethodNameVariant>
105105
GetMethodNameVariants(ConstString method_name) const override;
106106

107+
Language::FunctionNameInfo
108+
GetFunctionNameInfo(ConstString name) const override;
109+
107110
bool SymbolNameFitsToLanguage(Mangled mangled) const override;
108111

109112
lldb::TypeCategoryImplSP GetFormatters() override;

0 commit comments

Comments
 (0)