Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions lldb/include/lldb/Core/Module.h
Original file line number Diff line number Diff line change
Expand Up @@ -897,7 +897,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; }

Expand All @@ -923,7 +923,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
Expand Down
13 changes: 13 additions & 0 deletions lldb/include/lldb/Target/Language.h
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,19 @@ class Language : public PluginInterface {
return std::vector<Language::MethodNameVariant>();
};

class FunctionNameInfo {
public:
llvm::StringRef basename;
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.
///
Expand Down
1 change: 0 additions & 1 deletion lldb/source/Core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@ add_lldb_library(lldbCore
lldbTarget
lldbUtility
lldbPluginCPlusPlusLanguage
lldbPluginObjCLanguage
${LLDB_CURSES_LIBS}

CLANG_LIBS
Expand Down
156 changes: 53 additions & 103 deletions lldb/source/Core/Module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,9 @@
#endif

#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
#include "Plugins/Language/ObjC/ObjCLanguage.h"

#ifdef LLDB_ENABLE_SWIFT
#include "Plugins/TypeSystem/Swift/SwiftASTContext.h"
#include "Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.h"
#endif // LLDB_ENABLE_SWIFT

#include "llvm/ADT/STLExtras.h"
Expand Down Expand Up @@ -640,126 +638,78 @@ 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;
auto collect_language_plugins = [&languages](Language *lang) {
languages.push_back(lang);
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;
#ifdef LLDB_ENABLE_SWIFT
else if (SwiftLanguageRuntime::IsSwiftMangledName(name.GetStringRef()))
m_name_type_mask = eFunctionNameTypeFull;
#endif // LLDB_ENABLE_SWIFT
else if (Language::LanguageIsC(language)) {
m_name_type_mask = eFunctionNameTypeFull;
if (language_type == eLanguageTypeUnknown) {
Language::ForEach(collect_language_plugins);
for (Language *lang : languages) {
Language::FunctionNameInfo info = lang->GetFunctionNameInfo(name);
if (info.func_name_type != eFunctionNameTypeNone) {
m_name_type_mask |= info.func_name_type;
if (basename.empty() && !info.basename.empty())
basename = info.basename;
}
}
} else {
if ((language == eLanguageTypeUnknown ||
Language::LanguageIsObjC(language)) &&
ObjCLanguage::IsPossibleObjCSelector(name_cstr))
m_name_type_mask |= eFunctionNameTypeSelector;

CPlusPlusLanguage::MethodName cpp_method(name);

#ifdef LLDB_ENABLE_SWIFT
SwiftLanguageRuntime::MethodName swift_method(name, true);

if ((language == eLanguageTypeUnknown ||
language == eLanguageTypeSwift) &&
swift_method.IsValid())
basename = swift_method.GetBasename();
#endif // LLDB_ENABLE_SWIFT
if ((language == eLanguageTypeUnknown ||
Language::LanguageIsCFamily(language)) &&
cpp_method.IsValid())
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;
}
}

// 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);

// BEGIN SWIFT
#ifdef LLDB_ENABLE_SWIFT
SwiftLanguageRuntime::MethodName swift_method(name, true);
if (swift_method.IsValid())
basename = swift_method.GetBasename();
#endif // LLDB_ENABLE_SWIFT
if (cpp_method.IsValid())
basename = cpp_method.GetBasename();
if (!basename.empty()) {
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;
}
// END SWIFT
} 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 {
Language::ForEach(collect_language_plugins);
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;
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;
}
}

Expand Down
36 changes: 36 additions & 0 deletions lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,42 @@ 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;
return info;
}

CPlusPlusLanguage::MethodName method(name);
llvm::StringRef basename = method.GetBasename();
if (basename.empty()) {
llvm::StringRef context;
if (CPlusPlusLanguage::ExtractContextAndIdentifier(
name.GetCString(), context, info.basename)) {
info.func_name_type |=
(lldb::eFunctionNameTypeMethod | eFunctionNameTypeBase);
} else {
info.func_name_type |= lldb::eFunctionNameTypeFull;
}
} else {
info.basename = basename;
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);
Expand Down
3 changes: 3 additions & 0 deletions lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

static bool IsCPPMangledName(llvm::StringRef name);
Expand Down
16 changes: 16 additions & 0 deletions lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
3 changes: 3 additions & 0 deletions lldb/source/Plugins/Language/ObjC/ObjCLanguage.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
22 changes: 22 additions & 0 deletions lldb/source/Plugins/Language/Swift/SwiftLanguage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,28 @@ SwiftLanguage::GetMethodNameVariants(ConstString method_name) const {
return variant_names;
}

Language::FunctionNameInfo
SwiftLanguage::GetFunctionNameInfo(ConstString name) const {
FunctionNameInfo info;
info.func_name_type = eFunctionNameTypeNone;

if (SwiftLanguageRuntime::IsSwiftMangledName(name.GetStringRef())) {
info.func_name_type = eFunctionNameTypeFull;
return info;
}

SwiftLanguageRuntime::MethodName method(name);
llvm::StringRef basename = method.GetBasename();
if (basename.empty()) {
info.func_name_type |= eFunctionNameTypeFull;
} else {
info.basename = basename;
info.func_name_type |= (eFunctionNameTypeMethod | eFunctionNameTypeBase);
}

return info;
}

static void LoadSwiftFormatters(lldb::TypeCategoryImplSP swift_category_sp) {
if (!swift_category_sp)
return;
Expand Down
3 changes: 3 additions & 0 deletions lldb/source/Plugins/Language/Swift/SwiftLanguage.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ class SwiftLanguage : public Language {
std::vector<Language::MethodNameVariant>
GetMethodNameVariants(ConstString method_name) const override;

Language::FunctionNameInfo
GetFunctionNameInfo(ConstString name) const override;

lldb::TypeCategoryImplSP GetFormatters() override;

HardcodedFormatters::HardcodedSummaryFinder GetHardcodedSummaries() override;
Expand Down