[Lldb-commits] [lldb] Revert "[LLDB] Refactored CPlusPlusLanguage::MethodName to break lldb-server dependencies" (PR #134995)
via lldb-commits
lldb-commits at lists.llvm.org
Wed Apr 9 05:17:00 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-lldb
Author: David Spickett (DavidSpickett)
<details>
<summary>Changes</summary>
Reverts llvm/llvm-project#<!-- -->132274
Broke a test on LLDB Widows on Arm:
https://lab.llvm.org/buildbot/#/builders/141/builds/7726
```
FAIL: test_dwarf (lldbsuite.test.lldbtest.TestExternCSymbols.test_dwarf)
<...>
self.assertTrue(self.res.Succeeded(), msg + output)
AssertionError: False is not true : Command 'expression -- foo()' did not return successfully
Error output:
error: Couldn't look up symbols:
int foo(void)
Hint: The expression tried to call a function that is not present in the target, perhaps because it was optimized out by the compiler.
```
---
Patch is 38.59 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/134995.diff
17 Files Affected:
- (modified) lldb/include/lldb/Core/Mangled.h (-2)
- (modified) lldb/include/lldb/Core/RichManglingContext.h (+14-2)
- (modified) lldb/include/lldb/Target/Language.h (-98)
- (modified) lldb/source/Core/CMakeLists.txt (+4-1)
- (modified) lldb/source/Core/Mangled.cpp (+5-5)
- (modified) lldb/source/Core/Module.cpp (+88-63)
- (modified) lldb/source/Core/RichManglingContext.cpp (+13-9)
- (modified) lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp (+5-6)
- (modified) lldb/source/Plugins/Language/CMakeLists.txt (-2)
- (modified) lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp (+76-52)
- (modified) lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h (+49-9)
- (modified) lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp (-13)
- (modified) lldb/source/Plugins/Language/ObjC/ObjCLanguage.h (-3)
- (modified) lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp (+2-2)
- (modified) lldb/unittests/Core/CMakeLists.txt (-1)
- (modified) lldb/unittests/Core/RichManglingContextTest.cpp (-7)
- (modified) lldb/unittests/Language/CPlusPlus/CPlusPlusLanguageTest.cpp (+11-11)
``````````diff
diff --git a/lldb/include/lldb/Core/Mangled.h b/lldb/include/lldb/Core/Mangled.h
index 7db63eeeb6ee0..5988d919a89b8 100644
--- a/lldb/include/lldb/Core/Mangled.h
+++ b/lldb/include/lldb/Core/Mangled.h
@@ -246,8 +246,6 @@ class Mangled {
/// for s, otherwise the enumerator for the mangling scheme detected.
static Mangled::ManglingScheme GetManglingScheme(llvm::StringRef const name);
- static bool IsMangledName(llvm::StringRef name);
-
/// Decode a serialized version of this object from data.
///
/// \param data
diff --git a/lldb/include/lldb/Core/RichManglingContext.h b/lldb/include/lldb/Core/RichManglingContext.h
index 50ec2ae361098..3b79924e88a9a 100644
--- a/lldb/include/lldb/Core/RichManglingContext.h
+++ b/lldb/include/lldb/Core/RichManglingContext.h
@@ -12,7 +12,6 @@
#include "lldb/lldb-forward.h"
#include "lldb/lldb-private.h"
-#include "lldb/Target/Language.h"
#include "lldb/Utility/ConstString.h"
#include "llvm/ADT/Any.h"
@@ -68,7 +67,11 @@ class RichManglingContext {
char *m_ipd_buf;
size_t m_ipd_buf_size = 2048;
- std::unique_ptr<Language::MethodName> m_cxx_method_parser;
+ /// Members for PluginCxxLanguage
+ /// Cannot forward declare inner class CPlusPlusLanguage::MethodName. The
+ /// respective header is in Plugins and including it from here causes cyclic
+ /// dependency. Instead keep a llvm::Any and cast it on-access in the cpp.
+ llvm::Any m_cxx_method_parser;
/// Clean up memory when using PluginCxxLanguage
void ResetCxxMethodParser();
@@ -78,6 +81,15 @@ class RichManglingContext {
/// Uniform handling of string buffers for ItaniumPartialDemangler.
llvm::StringRef processIPDStrResult(char *ipd_res, size_t res_len);
+
+ /// Cast the given parser to the given type. Ideally we would have a type
+ /// trait to deduce \a ParserT from a given InfoProvider, but unfortunately we
+ /// can't access CPlusPlusLanguage::MethodName from within the header.
+ template <class ParserT> static ParserT *get(llvm::Any parser) {
+ assert(parser.has_value());
+ assert(llvm::any_cast<ParserT *>(&parser));
+ return *llvm::any_cast<ParserT *>(&parser);
+ }
};
} // namespace lldb_private
diff --git a/lldb/include/lldb/Target/Language.h b/lldb/include/lldb/Target/Language.h
index d46969cb3b4e4..b699a90aff8e4 100644
--- a/lldb/include/lldb/Target/Language.h
+++ b/lldb/include/lldb/Target/Language.h
@@ -214,104 +214,6 @@ class Language : public PluginInterface {
return std::vector<Language::MethodNameVariant>();
};
- class MethodName {
- public:
- MethodName() {}
-
- MethodName(ConstString full)
- : m_full(full), m_basename(), m_context(), m_arguments(),
- m_qualifiers(), m_return_type(), m_scope_qualified(), m_parsed(false),
- m_parse_error(false) {}
-
- virtual ~MethodName() {};
-
- void Clear() {
- m_full.Clear();
- m_basename = llvm::StringRef();
- m_context = llvm::StringRef();
- m_arguments = llvm::StringRef();
- m_qualifiers = llvm::StringRef();
- m_return_type = llvm::StringRef();
- m_scope_qualified.clear();
- m_parsed = false;
- m_parse_error = false;
- }
-
- bool IsValid() {
- if (!m_parsed)
- Parse();
- if (m_parse_error)
- return false;
- return (bool)m_full;
- }
-
- ConstString GetFullName() const { return m_full; }
-
- llvm::StringRef GetBasename() {
- if (!m_parsed)
- Parse();
- return m_basename;
- }
-
- llvm::StringRef GetContext() {
- if (!m_parsed)
- Parse();
- return m_context;
- }
-
- llvm::StringRef GetArguments() {
- if (!m_parsed)
- Parse();
- return m_arguments;
- }
-
- llvm::StringRef GetQualifiers() {
- if (!m_parsed)
- Parse();
- return m_qualifiers;
- }
-
- llvm::StringRef GetReturnType() {
- if (!m_parsed)
- Parse();
- return m_return_type;
- }
-
- std::string GetScopeQualifiedName() {
- if (!m_parsed)
- Parse();
- return m_scope_qualified;
- }
-
- protected:
- virtual void Parse() {
- m_parsed = true;
- m_parse_error = true;
- }
-
- ConstString m_full; // Full name:
- // "size_t lldb::SBTarget::GetBreakpointAtIndex(unsigned
- // int) const"
- llvm::StringRef m_basename; // Basename: "GetBreakpointAtIndex"
- llvm::StringRef m_context; // Decl context: "lldb::SBTarget"
- llvm::StringRef m_arguments; // Arguments: "(unsigned int)"
- llvm::StringRef m_qualifiers; // Qualifiers: "const"
- llvm::StringRef m_return_type; // Return type: "size_t"
- std::string m_scope_qualified;
- bool m_parsed = false;
- bool m_parse_error = false;
- };
-
- virtual std::unique_ptr<Language::MethodName>
- GetMethodName(ConstString name) const {
- return std::make_unique<Language::MethodName>(name);
- };
-
- virtual std::pair<lldb::FunctionNameType, llvm::StringRef>
- GetFunctionNameInfo(ConstString name) const {
- return std::pair{lldb::eFunctionNameTypeNone, llvm::StringRef()};
- };
-
/// 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 f09b451ac414d..0a08da0fec230 100644
--- a/lldb/source/Core/CMakeLists.txt
+++ b/lldb/source/Core/CMakeLists.txt
@@ -16,7 +16,8 @@ if (LLDB_ENABLE_CURSES)
endif()
endif()
-add_lldb_library(lldbCore NO_PLUGIN_DEPENDENCIES
+# TODO: Add property `NO_PLUGIN_DEPENDENCIES` to lldbCore
+add_lldb_library(lldbCore
Address.cpp
AddressRange.cpp
AddressRangeListImpl.cpp
@@ -70,6 +71,8 @@ add_lldb_library(lldbCore NO_PLUGIN_DEPENDENCIES
lldbUtility
lldbValueObject
lldbVersion
+ lldbPluginCPlusPlusLanguage
+ lldbPluginObjCLanguage
${LLDB_CURSES_LIBS}
CLANG_LIBS
diff --git a/lldb/source/Core/Mangled.cpp b/lldb/source/Core/Mangled.cpp
index c41f0fdb5ff1b..ddaaedea04183 100644
--- a/lldb/source/Core/Mangled.cpp
+++ b/lldb/source/Core/Mangled.cpp
@@ -33,12 +33,12 @@
#include <cstring>
using namespace lldb_private;
-#pragma mark Mangled
-
-bool Mangled::IsMangledName(llvm::StringRef name) {
- return Mangled::GetManglingScheme(name) != Mangled::eManglingSchemeNone;
+static inline bool cstring_is_mangled(llvm::StringRef s) {
+ return Mangled::GetManglingScheme(s) != Mangled::eManglingSchemeNone;
}
+#pragma mark Mangled
+
Mangled::ManglingScheme Mangled::GetManglingScheme(llvm::StringRef const name) {
if (name.empty())
return Mangled::eManglingSchemeNone;
@@ -121,7 +121,7 @@ int Mangled::Compare(const Mangled &a, const Mangled &b) {
void Mangled::SetValue(ConstString name) {
if (name) {
- if (IsMangledName(name.GetStringRef())) {
+ if (cstring_is_mangled(name.GetStringRef())) {
m_demangled.Clear();
m_mangled = name;
} else {
diff --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp
index ea6c2a1679aa0..53dc6fcde0381 100644
--- a/lldb/source/Core/Module.cpp
+++ b/lldb/source/Core/Module.cpp
@@ -52,6 +52,9 @@
#include "lldb/Host/windows/PosixApi.h"
#endif
+#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
+#include "Plugins/Language/ObjC/ObjCLanguage.h"
+
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/DJB.h"
@@ -638,75 +641,98 @@ void Module::FindCompileUnits(const FileSpec &path,
Module::LookupInfo::LookupInfo(ConstString name,
FunctionNameType name_type_mask,
LanguageType language)
- : m_name(name), m_lookup_name(name), m_language(language) {
+ : m_name(name), m_lookup_name(), m_language(language) {
+ const char *name_cstr = name.GetCString();
llvm::StringRef basename;
-
- std::vector<Language *> languages;
- auto collect_language_plugins = [&languages](Language *lang) {
- languages.push_back(lang);
- return true;
- };
+ llvm::StringRef context;
if (name_type_mask & eFunctionNameTypeAuto) {
- if (language == eLanguageTypeUnknown) {
- Language::ForEach(collect_language_plugins);
- for (Language *lang : languages) {
- auto info = lang->GetFunctionNameInfo(name);
- if (info.first != eFunctionNameTypeNone) {
- m_name_type_mask |= info.first;
- basename = info.second;
- break;
- }
- }
+ 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;
} else {
- if (auto *lang = Language::FindPlugin(language)) {
- auto info = lang->GetFunctionNameInfo(name);
- m_name_type_mask = info.first;
- basename = info.second;
+ 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);
}
}
-
- // 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 (language == eLanguageTypeUnknown) {
- Language::ForEach(collect_language_plugins);
- for (Language *lang : languages) {
- auto info = lang->GetFunctionNameInfo(name);
- if (info.first & m_name_type_mask) {
- m_name_type_mask &= info.first;
- basename = info.second;
- break;
+ 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;
}
+ } 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);
}
- } else {
- if (auto *lang = Language::FindPlugin(language)) {
- auto info = lang->GetFunctionNameInfo(name);
- if (info.first & 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.first;
- basename = info.second;
- }
+ }
+
+ 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);
}
}
}
if (!basename.empty()) {
- // 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.
+ // 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
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;
}
}
@@ -765,8 +791,7 @@ void Module::LookupInfo::Prune(SymbolContextList &sc_list,
// "func" and specified eFunctionNameTypeFull, but we might have found
// "a::func()", "a::b::func()", "c::func()", "func()" and "func". Only
// "func()" and "func" should end up matching.
- auto *lang = Language::FindPlugin(eLanguageTypeC_plus_plus);
- if (lang && m_name_type_mask == eFunctionNameTypeFull) {
+ if (m_name_type_mask == eFunctionNameTypeFull) {
SymbolContext sc;
size_t i = start_idx;
while (i < sc_list.GetSize()) {
@@ -777,21 +802,20 @@ void Module::LookupInfo::Prune(SymbolContextList &sc_list,
ConstString mangled_name(sc.GetFunctionName(Mangled::ePreferMangled));
ConstString full_name(sc.GetFunctionName());
if (mangled_name != m_name && full_name != m_name) {
- std::unique_ptr<Language::MethodName> cpp_method =
- lang->GetMethodName(full_name);
- if (cpp_method->IsValid()) {
- if (cpp_method->GetContext().empty()) {
- if (cpp_method->GetBasename().compare(m_name) != 0) {
+ CPlusPlusLanguage::MethodName cpp_method(full_name);
+ if (cpp_method.IsValid()) {
+ if (cpp_method.GetContext().empty()) {
+ if (cpp_method.GetBasename().compare(m_name) != 0) {
sc_list.RemoveContextAtIndex(i);
continue;
}
} else {
std::string qualified_name;
llvm::StringRef anon_prefix("(anonymous namespace)");
- if (cpp_method->GetContext() == anon_prefix)
- qualified_name = cpp_method->GetBasename().str();
+ if (cpp_method.GetContext() == anon_prefix)
+ qualified_name = cpp_method.GetBasename().str();
else
- qualified_name = cpp_method->GetScopeQualifiedName();
+ qualified_name = cpp_method.GetScopeQualifiedName();
if (qualified_name != m_name.GetCString()) {
sc_list.RemoveContextAtIndex(i);
continue;
@@ -964,7 +988,8 @@ DebuggersOwningModuleRequestingInterruption(Module &module) {
for (auto debugger_sp : requestors) {
if (!debugger_sp->InterruptRequested())
continue;
- if (debugger_sp->GetTargetList().AnyTargetContainsModule(module))
+ if (debugger_sp->GetTargetList()
+ .AnyTargetContainsModule(module))
interruptors.push_back(debugger_sp);
}
return interruptors;
diff --git a/lldb/source/Core/RichManglingContext.cpp b/lldb/source/Core/RichManglingContext.cpp
index 82582a5d675a9..b68c9e11581b4 100644
--- a/lldb/source/Core/RichManglingContext.cpp
+++ b/lldb/source/Core/RichManglingContext.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "lldb/Core/RichManglingContext.h"
+#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
#include "lldb/Utility/LLDBLog.h"
#include "llvm/ADT/StringRef.h"
@@ -23,8 +24,9 @@ RichManglingContext::~RichManglingContext() {
void RichManglingContext::ResetCxxMethodParser() {
// If we want to support parsers for other languages some day, we need a
// switch here to delete the correct parser type.
- if (m_cxx_method_parser) {
+ if (m_cxx_method_parser.has_value()) {
assert(m_provider == PluginCxxLanguage);
+ delete get<CPlusPlusLanguage::MethodName>(m_cxx_method_parser);
m_cxx_method_parser.reset();
}
}
@@ -56,11 +58,8 @@ bool RichManglingContext::FromItaniumName(ConstString mangled) {
}
bool RichManglingContext::FromCxxMethodName(ConstString demangled) {
- auto *lang = Language::FindPlugin(eLanguageTypeC_plus_plus);
- if (!lang)
- return false;
ResetProvider(PluginCxxLanguage);
- m_cxx_method_parser = lang->GetMethodName(demangled);
+ m_cxx_method_parser = new CPlusPlusLanguage::MethodName(demangled);
return true;
}
@@ -71,7 +70,8 @@ bool RichManglingContext::IsCtorOrDtor() const {
return m_ipd.isCtorOrDtor();
case PluginCxxLanguage: {
// We can only check for destructors here.
- auto base_name = m_cxx_method_parser->GetBasename();
+ auto base_name =
+ get<CPlusPlusLanguage::MethodName>(m_cxx_method_parser)->GetBasename();
return base_name.starts_with("~");
}
case None:
@@ -118,7 +118,8 @@ llvm::StringRef RichManglingContext::ParseFunctionBaseName() {
return processIPDStrResult(buf, n);
}
case PluginCxxLanguage:
- return m_cxx_method_parser->GetBasename();
+ return get<CPlusPlusLanguage::MethodName>(m_cxx_method_parser)
+ ->GetBasename();
case None:
return {};
}
@@ -134,7 +135,8 @@ llvm::StringRef RichManglingContext::ParseFunctionDeclContextName() {
return processIPDStrResult(buf, n);
}
case PluginCxxLanguage:
- return m_cxx_method_parser->GetContext();
+ return get<CPlusPlusLanguage::MethodName>(m_cxx_method_parser)
+ ->GetContext();
case None:
return {};
}
@@ -150,7 +152,9 @@ llvm::StringRef RichManglingContext::ParseFullName() {
return processIPDStrResult(buf, n);
}
case PluginCxxLanguage:
- return m_cxx_method_parser->GetFullName().GetStringRef();
+ return get<CPlusPlusLanguage::MethodName>(m_cxx_method_parser)
+ ->GetFullName()
+ .GetStringRef();
case None:
return {};
}
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
index 667cb8a900459..9e96f6557c7ba 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
@@ -18,7 +18,6 @@
#include "NameSearchContext.h"
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Core/Address.h"
-#include "lldb/Core/Mangled.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Expression/DiagnosticManager.h"
@@ -36,7 +35,6 @@
#include "lldb/Symbol/Variable.h"
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/ExecutionContext.h"
-#include "lldb/Target/Language.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StackFrame.h"
@@ -58,6 +56,7 @@
#include "clang/AST/DeclarationName.h"
#include "clang/AST/RecursiveASTVisitor.h"
+#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
#include "Plugins/Lan...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/134995
More information about the lldb-commits
mailing list