forked from OSchip/llvm-project
[Breakpoint] Make breakpoint language agnostic
Summary: Breakpoint shouldn't need to depend on any specific details from a programming language. Currently the only language-specific detail it takes advantage of are the different qualified names an objective-c method name might have when adding a name lookup. This is reasonably generalizable. The current method name I introduced is "GetVariantMethodNames", which I'm not particularly tied to. If you have a better suggestion, please do let me know. Reviewers: JDevlieghere, jingham, clayborg Subscribers: mgorny, lldb-commits Differential Revision: https://reviews.llvm.org/D61746 llvm-svn: 360509
This commit is contained in:
parent
3814d60035
commit
58a638b79f
|
@ -190,6 +190,14 @@ public:
|
|||
|
||||
virtual const char *GetLanguageSpecificTypeLookupHelp();
|
||||
|
||||
// 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<ConstString>
|
||||
GetMethodNameVariants(ConstString method_name) const {
|
||||
return std::vector<ConstString>();
|
||||
};
|
||||
|
||||
// if an individual data formatter can apply to several types and cross a
|
||||
// language boundary it makes sense for individual languages to want to
|
||||
// customize the printing of values of that type by appending proper
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
|
||||
#include "lldb/Breakpoint/BreakpointResolverName.h"
|
||||
|
||||
#include "Plugins/Language/ObjC/ObjCLanguage.h"
|
||||
#include "lldb/Breakpoint/BreakpointLocation.h"
|
||||
#include "lldb/Core/Architecture.h"
|
||||
#include "lldb/Core/Module.h"
|
||||
|
@ -17,6 +16,7 @@
|
|||
#include "lldb/Symbol/Symbol.h"
|
||||
#include "lldb/Symbol/SymbolContext.h"
|
||||
#include "lldb/Target/Target.h"
|
||||
#include "lldb/Target/Language.h"
|
||||
#include "lldb/Utility/Log.h"
|
||||
#include "lldb/Utility/StreamString.h"
|
||||
|
||||
|
@ -218,20 +218,27 @@ StructuredData::ObjectSP BreakpointResolverName::SerializeToStructuredData() {
|
|||
|
||||
void BreakpointResolverName::AddNameLookup(ConstString name,
|
||||
FunctionNameType name_type_mask) {
|
||||
ObjCLanguage::MethodName objc_method(name.GetCString(), false);
|
||||
if (objc_method.IsValid(false)) {
|
||||
std::vector<ConstString> objc_names;
|
||||
objc_method.GetFullNames(objc_names, true);
|
||||
for (ConstString objc_name : objc_names) {
|
||||
Module::LookupInfo lookup;
|
||||
lookup.SetName(name);
|
||||
lookup.SetLookupName(objc_name);
|
||||
lookup.SetNameTypeMask(eFunctionNameTypeFull);
|
||||
m_lookups.push_back(lookup);
|
||||
|
||||
Module::LookupInfo lookup(name, name_type_mask, m_language);
|
||||
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);
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
if (Language *lang = Language::FindPlugin(m_language)) {
|
||||
add_variant_funcs(lang);
|
||||
} else {
|
||||
Module::LookupInfo lookup(name, name_type_mask, m_language);
|
||||
m_lookups.push_back(lookup);
|
||||
// Most likely m_language is eLanguageTypeUnknown. We check each language for
|
||||
// possible variants or more qualified names and create lookups for those as
|
||||
// well.
|
||||
Language::ForEach(add_variant_funcs);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -30,7 +30,6 @@ add_lldb_library(lldbBreakpoint
|
|||
lldbSymbol
|
||||
lldbTarget
|
||||
lldbUtility
|
||||
lldbPluginObjCLanguage
|
||||
|
||||
LINK_COMPONENTS
|
||||
Support
|
||||
|
|
|
@ -220,43 +220,46 @@ ConstString ObjCLanguage::MethodName::GetFullNameWithoutCategory(
|
|||
return ConstString();
|
||||
}
|
||||
|
||||
size_t ObjCLanguage::MethodName::GetFullNames(std::vector<ConstString> &names,
|
||||
bool append) {
|
||||
if (!append)
|
||||
names.clear();
|
||||
if (IsValid(false)) {
|
||||
std::vector<ConstString>
|
||||
ObjCLanguage::GetMethodNameVariants(ConstString method_name) const {
|
||||
std::vector<ConstString> variant_names;
|
||||
ObjCLanguage::MethodName objc_method(method_name.GetCString(), false);
|
||||
if (!objc_method.IsValid(false)) {
|
||||
return variant_names;
|
||||
}
|
||||
|
||||
const bool is_class_method =
|
||||
objc_method.GetType() == MethodName::eTypeClassMethod;
|
||||
const bool is_instance_method =
|
||||
objc_method.GetType() == MethodName::eTypeInstanceMethod;
|
||||
ConstString name_sans_category =
|
||||
objc_method.GetFullNameWithoutCategory(/*empty_if_no_category*/ true);
|
||||
|
||||
if (is_class_method || is_instance_method) {
|
||||
if (name_sans_category)
|
||||
variant_names.emplace_back(name_sans_category);
|
||||
} else {
|
||||
StreamString strm;
|
||||
const bool is_class_method = m_type == eTypeClassMethod;
|
||||
const bool is_instance_method = m_type == eTypeInstanceMethod;
|
||||
ConstString category = GetCategory();
|
||||
if (is_class_method || is_instance_method) {
|
||||
names.push_back(m_full);
|
||||
if (category) {
|
||||
strm.Printf("%c[%s %s]", is_class_method ? '+' : '-',
|
||||
GetClassName().GetCString(), GetSelector().GetCString());
|
||||
names.emplace_back(strm.GetString());
|
||||
}
|
||||
} else {
|
||||
ConstString class_name = GetClassName();
|
||||
ConstString selector = GetSelector();
|
||||
strm.Printf("+[%s %s]", class_name.GetCString(), selector.GetCString());
|
||||
names.emplace_back(strm.GetString());
|
||||
|
||||
strm.Printf("+%s", objc_method.GetFullName().GetCString());
|
||||
variant_names.emplace_back(strm.GetString());
|
||||
strm.Clear();
|
||||
|
||||
strm.Printf("-%s", objc_method.GetFullName().GetCString());
|
||||
variant_names.emplace_back(strm.GetString());
|
||||
strm.Clear();
|
||||
|
||||
if (name_sans_category) {
|
||||
strm.Printf("+%s", name_sans_category.GetCString());
|
||||
variant_names.emplace_back(strm.GetString());
|
||||
strm.Clear();
|
||||
strm.Printf("-[%s %s]", class_name.GetCString(), selector.GetCString());
|
||||
names.emplace_back(strm.GetString());
|
||||
strm.Clear();
|
||||
if (category) {
|
||||
strm.Printf("+[%s(%s) %s]", class_name.GetCString(),
|
||||
category.GetCString(), selector.GetCString());
|
||||
names.emplace_back(strm.GetString());
|
||||
strm.Clear();
|
||||
strm.Printf("-[%s(%s) %s]", class_name.GetCString(),
|
||||
category.GetCString(), selector.GetCString());
|
||||
names.emplace_back(strm.GetString());
|
||||
}
|
||||
|
||||
strm.Printf("-%s", name_sans_category.GetCString());
|
||||
variant_names.emplace_back(strm.GetString());
|
||||
}
|
||||
}
|
||||
return names.size();
|
||||
|
||||
return variant_names;
|
||||
}
|
||||
|
||||
static void LoadObjCFormatters(TypeCategoryImplSP objc_category_sp) {
|
||||
|
|
|
@ -73,18 +73,6 @@ public:
|
|||
|
||||
ConstString GetSelector();
|
||||
|
||||
// Get all possible names for a method. Examples:
|
||||
// If name is "+[NSString(my_additions) myStringWithCString:]"
|
||||
// names[0] => "+[NSString(my_additions) myStringWithCString:]"
|
||||
// names[1] => "+[NSString myStringWithCString:]"
|
||||
// If name is specified without the leading '+' or '-' like
|
||||
// "[NSString(my_additions) myStringWithCString:]"
|
||||
// names[0] => "+[NSString(my_additions) myStringWithCString:]"
|
||||
// names[1] => "-[NSString(my_additions) myStringWithCString:]"
|
||||
// names[2] => "+[NSString myStringWithCString:]"
|
||||
// names[3] => "-[NSString myStringWithCString:]"
|
||||
size_t GetFullNames(std::vector<ConstString> &names, bool append);
|
||||
|
||||
protected:
|
||||
ConstString
|
||||
m_full; // Full name: "+[NSString(my_additions) myStringWithCString:]"
|
||||
|
@ -105,6 +93,18 @@ public:
|
|||
return lldb::eLanguageTypeObjC;
|
||||
}
|
||||
|
||||
// Get all possible names for a method. Examples:
|
||||
// If method_name is "+[NSString(my_additions) myStringWithCString:]"
|
||||
// variant_names[0] => "+[NSString myStringWithCString:]"
|
||||
// If name is specified without the leading '+' or '-' like
|
||||
// "[NSString(my_additions) myStringWithCString:]"
|
||||
// variant_names[0] => "+[NSString(my_additions) myStringWithCString:]"
|
||||
// variant_names[1] => "-[NSString(my_additions) myStringWithCString:]"
|
||||
// variant_names[2] => "+[NSString myStringWithCString:]"
|
||||
// variant_names[3] => "-[NSString myStringWithCString:]"
|
||||
std::vector<ConstString>
|
||||
GetMethodNameVariants(ConstString method_name) const override;
|
||||
|
||||
lldb::TypeCategoryImplSP GetFormatters() override;
|
||||
|
||||
std::vector<ConstString>
|
||||
|
|
Loading…
Reference in New Issue