Author: Dmitry Vasilyev Date: 2025-04-14T14:30:09+04:00 New Revision: e4a672bc17a2a7dc39e51c9f5e656d705312a12b
URL: https://github.com/llvm/llvm-project/commit/e4a672bc17a2a7dc39e51c9f5e656d705312a12b DIFF: https://github.com/llvm/llvm-project/commit/e4a672bc17a2a7dc39e51c9f5e656d705312a12b.diff LOG: [LLDB] Reapply refactored CPlusPlusLanguage::MethodName to break lldb-server dependencies (#135033) The original PR is #132274. Co-authored-by: @bulbazord Alex Langford Added: Modified: lldb/include/lldb/Core/Mangled.h lldb/include/lldb/Core/RichManglingContext.h lldb/include/lldb/Target/Language.h lldb/source/Core/CMakeLists.txt lldb/source/Core/Mangled.cpp lldb/source/Core/Module.cpp lldb/source/Core/RichManglingContext.cpp lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp lldb/source/Plugins/Language/ObjC/ObjCLanguage.h lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp lldb/unittests/Core/CMakeLists.txt lldb/unittests/Core/RichManglingContextTest.cpp lldb/unittests/Language/CPlusPlus/CPlusPlusLanguageTest.cpp lldb/unittests/Language/ObjC/ObjCLanguageTest.cpp Removed: ################################################################################ diff --git a/lldb/include/lldb/Core/Mangled.h b/lldb/include/lldb/Core/Mangled.h index 5988d919a89b8..7db63eeeb6ee0 100644 --- a/lldb/include/lldb/Core/Mangled.h +++ b/lldb/include/lldb/Core/Mangled.h @@ -246,6 +246,8 @@ 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 3b79924e88a9a..50ec2ae361098 100644 --- a/lldb/include/lldb/Core/RichManglingContext.h +++ b/lldb/include/lldb/Core/RichManglingContext.h @@ -12,6 +12,7 @@ #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" @@ -67,11 +68,7 @@ class RichManglingContext { char *m_ipd_buf; size_t m_ipd_buf_size = 2048; - /// 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; + std::unique_ptr<Language::MethodName> m_cxx_method_parser; /// Clean up memory when using PluginCxxLanguage void ResetCxxMethodParser(); @@ -81,15 +78,6 @@ 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 da2c2cc451dae..fa856843871e3 100644 --- a/lldb/include/lldb/Target/Language.h +++ b/lldb/include/lldb/Target/Language.h @@ -214,6 +214,104 @@ 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, std::optional<ConstString>> + GetFunctionNameInfo(ConstString name) const { + return std::pair{lldb::eFunctionNameTypeNone, std::nullopt}; + }; + /// 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 0a08da0fec230..f09b451ac414d 100644 --- a/lldb/source/Core/CMakeLists.txt +++ b/lldb/source/Core/CMakeLists.txt @@ -16,8 +16,7 @@ if (LLDB_ENABLE_CURSES) endif() endif() -# TODO: Add property `NO_PLUGIN_DEPENDENCIES` to lldbCore -add_lldb_library(lldbCore +add_lldb_library(lldbCore NO_PLUGIN_DEPENDENCIES Address.cpp AddressRange.cpp AddressRangeListImpl.cpp @@ -71,8 +70,6 @@ add_lldb_library(lldbCore 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 ddaaedea04183..56836a6e5663e 100644 --- a/lldb/source/Core/Mangled.cpp +++ b/lldb/source/Core/Mangled.cpp @@ -33,12 +33,12 @@ #include <cstring> using namespace lldb_private; -static inline bool cstring_is_mangled(llvm::StringRef s) { - return Mangled::GetManglingScheme(s) != Mangled::eManglingSchemeNone; -} - #pragma mark Mangled +bool Mangled::IsMangledName(llvm::StringRef name) { + return Mangled::GetManglingScheme(name) != Mangled::eManglingSchemeNone; +} + 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 (cstring_is_mangled(name.GetStringRef())) { + if (IsMangledName(name.GetStringRef())) { m_demangled.Clear(); m_mangled = name; } else { @@ -251,7 +251,7 @@ bool Mangled::GetRichManglingInfo(RichManglingContext &context, return false; } else { // Demangled successfully, we can try and parse it with - // CPlusPlusLanguage::MethodName. + // CPlusPlusLanguage::CxxMethodName. return context.FromCxxMethodName(m_demangled); } } diff --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp index 53dc6fcde0381..ad7046e596278 100644 --- a/lldb/source/Core/Module.cpp +++ b/lldb/source/Core/Module.cpp @@ -641,98 +641,70 @@ 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) { - const char *name_cstr = name.GetCString(); - llvm::StringRef basename; - llvm::StringRef context; + : m_name(name), m_lookup_name(name), m_language(language) { + std::optional<ConstString> basename; + + std::vector<Language *> languages; + { + std::vector<LanguageType> lang_types; + if (language != eLanguageTypeUnknown) + lang_types.push_back(language); + else + lang_types = {eLanguageTypeObjC, eLanguageTypeC_plus_plus}; + + for (LanguageType lang_type : lang_types) { + if (Language *lang = Language::FindPlugin(lang_type)) + languages.push_back(lang); + } + } 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; - else if (Language::LanguageIsC(language)) { - m_name_type_mask = eFunctionNameTypeFull; - } else { - 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); + for (Language *lang : languages) { + auto info = lang->GetFunctionNameInfo(name); + if (info.first != eFunctionNameTypeNone) { + m_name_type_mask |= info.first; + if (!basename && info.second) + basename = info.second; } } + + // 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); - 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); - } - } - - if (name_type_mask & eFunctionNameTypeSelector) { - if (!ObjCLanguage::IsPossibleObjCSelector(name_cstr)) { - m_name_type_mask &= ~(eFunctionNameTypeSelector); - if (m_name_type_mask == eFunctionNameTypeNone) - return; + for (Language *lang : languages) { + 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; + break; } - } - - // 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()) { + // Still try and get a basename in case someone specifies a name type mask + // of eFunctionNameTypeFull and a name like "A::func" 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); + info.first != eFunctionNameTypeNone && !basename && info.second) { + basename = info.second; + 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 - m_lookup_name.SetString(basename); + if (basename) { + // 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; } } @@ -791,7 +763,8 @@ 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. - if (m_name_type_mask == eFunctionNameTypeFull) { + auto *lang = Language::FindPlugin(eLanguageTypeC_plus_plus); + if (lang && m_name_type_mask == eFunctionNameTypeFull) { SymbolContext sc; size_t i = start_idx; while (i < sc_list.GetSize()) { @@ -802,20 +775,21 @@ 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) { - CPlusPlusLanguage::MethodName cpp_method(full_name); - if (cpp_method.IsValid()) { - if (cpp_method.GetContext().empty()) { - if (cpp_method.GetBasename().compare(m_name) != 0) { + 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) { 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; @@ -988,8 +962,7 @@ 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 b68c9e11581b4..82582a5d675a9 100644 --- a/lldb/source/Core/RichManglingContext.cpp +++ b/lldb/source/Core/RichManglingContext.cpp @@ -7,7 +7,6 @@ //===----------------------------------------------------------------------===// #include "lldb/Core/RichManglingContext.h" -#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" #include "lldb/Utility/LLDBLog.h" #include "llvm/ADT/StringRef.h" @@ -24,9 +23,8 @@ 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.has_value()) { + if (m_cxx_method_parser) { assert(m_provider == PluginCxxLanguage); - delete get<CPlusPlusLanguage::MethodName>(m_cxx_method_parser); m_cxx_method_parser.reset(); } } @@ -58,8 +56,11 @@ 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 = new CPlusPlusLanguage::MethodName(demangled); + m_cxx_method_parser = lang->GetMethodName(demangled); return true; } @@ -70,8 +71,7 @@ bool RichManglingContext::IsCtorOrDtor() const { return m_ipd.isCtorOrDtor(); case PluginCxxLanguage: { // We can only check for destructors here. - auto base_name = - get<CPlusPlusLanguage::MethodName>(m_cxx_method_parser)->GetBasename(); + auto base_name = m_cxx_method_parser->GetBasename(); return base_name.starts_with("~"); } case None: @@ -118,8 +118,7 @@ llvm::StringRef RichManglingContext::ParseFunctionBaseName() { return processIPDStrResult(buf, n); } case PluginCxxLanguage: - return get<CPlusPlusLanguage::MethodName>(m_cxx_method_parser) - ->GetBasename(); + return m_cxx_method_parser->GetBasename(); case None: return {}; } @@ -135,8 +134,7 @@ llvm::StringRef RichManglingContext::ParseFunctionDeclContextName() { return processIPDStrResult(buf, n); } case PluginCxxLanguage: - return get<CPlusPlusLanguage::MethodName>(m_cxx_method_parser) - ->GetContext(); + return m_cxx_method_parser->GetContext(); case None: return {}; } @@ -152,9 +150,7 @@ llvm::StringRef RichManglingContext::ParseFullName() { return processIPDStrResult(buf, n); } case PluginCxxLanguage: - return get<CPlusPlusLanguage::MethodName>(m_cxx_method_parser) - ->GetFullName() - .GetStringRef(); + return 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 9e96f6557c7ba..667cb8a900459 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp +++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp @@ -18,6 +18,7 @@ #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" @@ -35,6 +36,7 @@ #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" @@ -56,7 +58,6 @@ #include "clang/AST/DeclarationName.h" #include "clang/AST/RecursiveASTVisitor.h" -#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" #include "Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h" #include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h" @@ -1809,10 +1810,10 @@ void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context, const auto lang = function->GetCompileUnit()->GetLanguage(); const auto name = function->GetMangled().GetMangledName().AsCString(); - const bool extern_c = (Language::LanguageIsC(lang) && - !CPlusPlusLanguage::IsCPPMangledName(name)) || - (Language::LanguageIsObjC(lang) && - !Language::LanguageIsCPlusPlus(lang)); + const bool extern_c = + (Language::LanguageIsC(lang) && !Mangled::IsMangledName(name)) || + (Language::LanguageIsObjC(lang) && + !Language::LanguageIsCPlusPlus(lang)); if (!extern_c) { TypeSystem *type_system = function->GetDeclContext().GetTypeSystem(); diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp index 9bd48ec55022a..40b6563aeb410 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp @@ -62,9 +62,47 @@ void CPlusPlusLanguage::Terminate() { PluginManager::UnregisterPlugin(CreateInstance); } +std::unique_ptr<Language::MethodName> +CPlusPlusLanguage::GetMethodName(ConstString full_name) const { + std::unique_ptr<CxxMethodName> cpp_method = + std::make_unique<CxxMethodName>(full_name); + cpp_method->IsValid(); + return cpp_method; +} + +std::pair<FunctionNameType, std::optional<ConstString>> +CPlusPlusLanguage::GetFunctionNameInfo(ConstString name) const { + if (Mangled::IsMangledName(name.GetCString())) + return {eFunctionNameTypeFull, std::nullopt}; + + FunctionNameType func_name_type = eFunctionNameTypeNone; + CxxMethodName method(name); + llvm::StringRef basename = method.GetBasename(); + if (basename.empty()) { + llvm::StringRef context; + func_name_type |= + (ExtractContextAndIdentifier(name.GetCString(), context, basename) + ? (eFunctionNameTypeMethod | eFunctionNameTypeBase) + : eFunctionNameTypeFull); + } else { + func_name_type |= (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. + func_name_type &= ~(eFunctionNameTypeBase); + } + + if (basename.empty()) + return {func_name_type, std::nullopt}; + else + return {func_name_type, ConstString(basename)}; +} + bool CPlusPlusLanguage::SymbolNameFitsToLanguage(Mangled mangled) const { const char *mangled_name = mangled.GetMangledName().GetCString(); - return mangled_name && CPlusPlusLanguage::IsCPPMangledName(mangled_name); + return mangled_name && Mangled::IsMangledName(mangled_name); } ConstString CPlusPlusLanguage::GetDemangledFunctionNameWithoutArguments( @@ -81,7 +119,7 @@ ConstString CPlusPlusLanguage::GetDemangledFunctionNameWithoutArguments( // eventually handle eSymbolTypeData, // we will want this back) { - CPlusPlusLanguage::MethodName cxx_method(demangled_name); + CxxMethodName cxx_method(demangled_name); if (!cxx_method.GetBasename().empty()) { std::string shortname; if (!cxx_method.GetContext().empty()) @@ -106,17 +144,6 @@ Language *CPlusPlusLanguage::CreateInstance(lldb::LanguageType language) { return nullptr; } -void CPlusPlusLanguage::MethodName::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_parsed = false; - m_parse_error = false; -} - static bool ReverseFindMatchingChars(const llvm::StringRef &s, const llvm::StringRef &left_right_chars, size_t &left_pos, size_t &right_pos, @@ -181,7 +208,7 @@ static bool PrettyPrintFunctionNameWithArgs(Stream &out_stream, char const *full_name, ExecutionContextScope *exe_scope, VariableList const &args) { - CPlusPlusLanguage::MethodName cpp_method{ConstString(full_name)}; + CPlusPlusLanguage::CxxMethodName cpp_method{ConstString(full_name)}; if (!cpp_method.IsValid()) return false; @@ -208,7 +235,7 @@ static bool PrettyPrintFunctionNameWithArgs(Stream &out_stream, return true; } -bool CPlusPlusLanguage::MethodName::TrySimplifiedParse() { +bool CPlusPlusLanguage::CxxMethodName::TrySimplifiedParse() { // This method tries to parse simple method definitions which are presumably // most comman in user programs. Definitions that can be parsed by this // function don't have return types and templates in the name. @@ -251,7 +278,7 @@ bool CPlusPlusLanguage::MethodName::TrySimplifiedParse() { return false; } -void CPlusPlusLanguage::MethodName::Parse() { +void CPlusPlusLanguage::CxxMethodName::Parse() { if (!m_parsed && m_full) { if (TrySimplifiedParse()) { m_parse_error = false; @@ -268,55 +295,19 @@ void CPlusPlusLanguage::MethodName::Parse() { m_parse_error = true; } } + if (m_context.empty()) { + m_scope_qualified = std::string(m_basename); + } else { + m_scope_qualified = m_context; + m_scope_qualified += "::"; + m_scope_qualified += m_basename; + } m_parsed = true; } } -llvm::StringRef CPlusPlusLanguage::MethodName::GetBasename() { - if (!m_parsed) - Parse(); - return m_basename; -} - -llvm::StringRef CPlusPlusLanguage::MethodName::GetContext() { - if (!m_parsed) - Parse(); - return m_context; -} - -llvm::StringRef CPlusPlusLanguage::MethodName::GetArguments() { - if (!m_parsed) - Parse(); - return m_arguments; -} - -llvm::StringRef CPlusPlusLanguage::MethodName::GetQualifiers() { - if (!m_parsed) - Parse(); - return m_qualifiers; -} - -llvm::StringRef CPlusPlusLanguage::MethodName::GetReturnType() { - if (!m_parsed) - Parse(); - return m_return_type; -} - -std::string CPlusPlusLanguage::MethodName::GetScopeQualifiedName() { - if (!m_parsed) - Parse(); - if (m_context.empty()) - return std::string(m_basename); - - std::string res; - res += m_context; - res += "::"; - res += m_basename; - return res; -} - llvm::StringRef -CPlusPlusLanguage::MethodName::GetBasenameNoTemplateParameters() { +CPlusPlusLanguage::CxxMethodName::GetBasenameNoTemplateParameters() { llvm::StringRef basename = GetBasename(); size_t arg_start, arg_end; llvm::StringRef parens("<>", 2); @@ -326,7 +317,7 @@ CPlusPlusLanguage::MethodName::GetBasenameNoTemplateParameters() { return basename; } -bool CPlusPlusLanguage::MethodName::ContainsPath(llvm::StringRef path) { +bool CPlusPlusLanguage::CxxMethodName::ContainsPath(llvm::StringRef path) { if (!m_parsed) Parse(); @@ -375,21 +366,9 @@ bool CPlusPlusLanguage::MethodName::ContainsPath(llvm::StringRef path) { return false; } -bool CPlusPlusLanguage::IsCPPMangledName(llvm::StringRef name) { - // FIXME!! we should really run through all the known C++ Language plugins - // and ask each one if this is a C++ mangled name - - Mangled::ManglingScheme scheme = Mangled::GetManglingScheme(name); - - if (scheme == Mangled::eManglingSchemeNone) - return false; - - return true; -} - bool CPlusPlusLanguage::DemangledNameContainsPath(llvm::StringRef path, ConstString demangled) const { - MethodName demangled_name(demangled); + CxxMethodName demangled_name(demangled); return demangled_name.ContainsPath(path); } @@ -588,7 +567,7 @@ ConstString CPlusPlusLanguage::FindBestAlternateFunctionMangledName( if (!demangled) return ConstString(); - CPlusPlusLanguage::MethodName cpp_name(demangled); + CxxMethodName cpp_name(demangled); std::string scope_qualified_name = cpp_name.GetScopeQualifiedName(); if (!scope_qualified_name.size()) @@ -611,7 +590,7 @@ ConstString CPlusPlusLanguage::FindBestAlternateFunctionMangledName( Mangled mangled(alternate_mangled_name); ConstString demangled = mangled.GetDemangledName(); - CPlusPlusLanguage::MethodName alternate_cpp_name(demangled); + CxxMethodName alternate_cpp_name(demangled); if (!cpp_name.IsValid()) continue; diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h index 54f5a94388b92..b2b308f8e0c4d 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h +++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h @@ -25,42 +25,9 @@ class CPlusPlusLanguage : public Language { ClangHighlighter m_highlighter; public: - class MethodName { + class CxxMethodName : public Language::MethodName { public: - MethodName() - : m_full(), m_basename(), m_context(), m_arguments(), m_qualifiers() {} - - MethodName(ConstString s) - : m_full(s), m_basename(), m_context(), m_arguments(), m_qualifiers(), - m_parsed(false), m_parse_error(false) {} - - void Clear(); - - bool IsValid() { - if (!m_parsed) - Parse(); - if (m_parse_error) - return false; - return (bool)m_full; - } - - ConstString GetFullName() const { return m_full; } - - std::string GetScopeQualifiedName(); - - llvm::StringRef GetBasename(); - - llvm::StringRef GetContext(); - - llvm::StringRef GetArguments(); - - llvm::StringRef GetQualifiers(); - - /// Returns the methods return-type. - /// - /// Currently returns an empty llvm::StringRef - /// if the return-type is a function pointer. - llvm::StringRef GetReturnType(); + CxxMethodName(ConstString s) : Language::MethodName(s) {} bool ContainsPath(llvm::StringRef path); @@ -80,25 +47,20 @@ class CPlusPlusLanguage : public Language { llvm::StringRef GetBasenameNoTemplateParameters(); protected: - void Parse(); + void Parse() override; bool TrySimplifiedParse(); - - 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" - bool m_parsed = false; - bool m_parse_error = false; }; CPlusPlusLanguage() = default; ~CPlusPlusLanguage() override = default; + virtual std::unique_ptr<Language::MethodName> + GetMethodName(ConstString name) const override; + + std::pair<lldb::FunctionNameType, std::optional<ConstString>> + GetFunctionNameInfo(ConstString name) const override; + lldb::LanguageType GetLanguageType() const override { return lldb::eLanguageTypeC_plus_plus; } @@ -143,12 +105,10 @@ class CPlusPlusLanguage : public Language { FunctionNameRepresentation representation, Stream &s) override; - static bool IsCPPMangledName(llvm::StringRef name); - // Extract C++ context and identifier from a string using heuristic matching // (as opposed to - // CPlusPlusLanguage::MethodName which has to have a fully qualified C++ name - // with parens and arguments. + // CPlusPlusLanguage::CxxMethodName which has to have a fully qualified C++ + // name with parens and arguments. // If the name is a lone C identifier (e.g. C) or a qualified C identifier // (e.g. A::B::C) it will return true, // and identifier will be the identifier (C and C respectively) and the diff --git a/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp b/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp index 2ae203405cbba..c835b439a64dd 100644 --- a/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp +++ b/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp @@ -60,8 +60,8 @@ Language *ObjCLanguage::CreateInstance(lldb::LanguageType language) { } } -std::optional<const ObjCLanguage::MethodName> -ObjCLanguage::MethodName::Create(llvm::StringRef name, bool strict) { +std::optional<const ObjCLanguage::ObjCMethodName> +ObjCLanguage::ObjCMethodName::Create(llvm::StringRef name, bool strict) { if (name.empty()) return std::nullopt; @@ -96,11 +96,11 @@ ObjCLanguage::MethodName::Create(llvm::StringRef name, bool strict) { // If we've gotten here, we're confident that this looks enough like an // Objective-C method to treat it like one. - ObjCLanguage::MethodName method_name(name, type); + ObjCLanguage::ObjCMethodName method_name(name, type); return method_name; } -llvm::StringRef ObjCLanguage::MethodName::GetClassName() const { +llvm::StringRef ObjCLanguage::ObjCMethodName::GetClassName() const { llvm::StringRef full = m_full; const size_t class_start_pos = (full.front() == '[' ? 1 : 2); const size_t paren_pos = full.find('(', class_start_pos); @@ -113,14 +113,14 @@ llvm::StringRef ObjCLanguage::MethodName::GetClassName() const { return full.substr(class_start_pos, space_pos - class_start_pos); } -llvm::StringRef ObjCLanguage::MethodName::GetClassNameWithCategory() const { +llvm::StringRef ObjCLanguage::ObjCMethodName::GetClassNameWithCategory() const { llvm::StringRef full = m_full; const size_t class_start_pos = (full.front() == '[' ? 1 : 2); const size_t space_pos = full.find(' ', class_start_pos); return full.substr(class_start_pos, space_pos - class_start_pos); } -llvm::StringRef ObjCLanguage::MethodName::GetSelector() const { +llvm::StringRef ObjCLanguage::ObjCMethodName::GetSelector() const { llvm::StringRef full = m_full; const size_t space_pos = full.find(' '); if (space_pos == llvm::StringRef::npos) @@ -129,7 +129,7 @@ llvm::StringRef ObjCLanguage::MethodName::GetSelector() const { return full.substr(space_pos + 1, closing_bracket - space_pos - 1); } -llvm::StringRef ObjCLanguage::MethodName::GetCategory() const { +llvm::StringRef ObjCLanguage::ObjCMethodName::GetCategory() const { llvm::StringRef full = m_full; const size_t open_paren_pos = full.find('('); const size_t close_paren_pos = full.find(')'); @@ -142,7 +142,7 @@ llvm::StringRef ObjCLanguage::MethodName::GetCategory() const { close_paren_pos - (open_paren_pos + 1)); } -std::string ObjCLanguage::MethodName::GetFullNameWithoutCategory() const { +std::string ObjCLanguage::ObjCMethodName::GetFullNameWithoutCategory() const { llvm::StringRef full = m_full; const size_t open_paren_pos = full.find('('); const size_t close_paren_pos = full.find(')'); @@ -179,8 +179,8 @@ std::string ObjCLanguage::MethodName::GetFullNameWithoutCategory() const { std::vector<Language::MethodNameVariant> ObjCLanguage::GetMethodNameVariants(ConstString method_name) const { std::vector<Language::MethodNameVariant> variant_names; - std::optional<const ObjCLanguage::MethodName> objc_method = - ObjCLanguage::MethodName::Create(method_name.GetStringRef(), false); + std::optional<const ObjCLanguage::ObjCMethodName> objc_method = + ObjCLanguage::ObjCMethodName::Create(method_name.GetStringRef(), false); if (!objc_method) return variant_names; @@ -222,6 +222,19 @@ ObjCLanguage::GetMethodNameVariants(ConstString method_name) const { return variant_names; } +std::pair<FunctionNameType, std::optional<ConstString>> +ObjCLanguage::GetFunctionNameInfo(ConstString name) const { + FunctionNameType func_name_type = eFunctionNameTypeNone; + + if (ObjCLanguage::IsPossibleObjCMethodName(name.GetCString())) + func_name_type = eFunctionNameTypeFull; + + if (ObjCLanguage::IsPossibleObjCSelector(name.GetCString())) + func_name_type |= eFunctionNameTypeSelector; + + return {func_name_type, std::nullopt}; +} + bool ObjCLanguage::SymbolNameFitsToLanguage(Mangled mangled) const { ConstString demangled_name = mangled.GetDemangledName(); if (!demangled_name) diff --git a/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h b/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h index 6d265a9be5277..a68ea41c723de 100644 --- a/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h +++ b/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h @@ -23,9 +23,9 @@ class ObjCLanguage : public Language { ClangHighlighter m_highlighter; public: - class MethodName { + class ObjCMethodName { public: - /// The static factory method for creating a MethodName. + /// The static factory method for creating a ObjCMethodName. /// /// \param[in] name /// The name of the method. @@ -35,9 +35,9 @@ class ObjCLanguage : public Language { /// front of the name. /// /// \return If the name failed to parse as a valid Objective-C method name, - /// returns std::nullopt. Otherwise returns a const MethodName. - static std::optional<const MethodName> Create(llvm::StringRef name, - bool strict); + /// returns std::nullopt. Otherwise returns a const ObjCMethodName. + static std::optional<const ObjCMethodName> Create(llvm::StringRef name, + bool strict); /// Determines if this method is a class method /// @@ -112,7 +112,7 @@ class ObjCLanguage : public Language { protected: enum Type { eTypeUnspecified, eTypeClassMethod, eTypeInstanceMethod }; - MethodName(llvm::StringRef name, Type type) + ObjCMethodName(llvm::StringRef name, Type type) : m_full(name.str()), m_type(type) {} const std::string m_full; @@ -142,6 +142,9 @@ class ObjCLanguage : public Language { std::vector<Language::MethodNameVariant> GetMethodNameVariants(ConstString method_name) const override; + std::pair<lldb::FunctionNameType, std::optional<ConstString>> + GetFunctionNameInfo(ConstString name) const override; + bool SymbolNameFitsToLanguage(Mangled mangled) const override; lldb::TypeCategoryImplSP GetFormatters() override; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index 0b632751574ad..f22fcbab557a0 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -1066,7 +1066,7 @@ ConvertDWARFCallingConventionToClang(const ParsedDWARFTypeAttributes &attrs) { } bool DWARFASTParserClang::ParseObjCMethod( - const ObjCLanguage::MethodName &objc_method, const DWARFDIE &die, + const ObjCLanguage::ObjCMethodName &objc_method, const DWARFDIE &die, CompilerType clang_type, const ParsedDWARFTypeAttributes &attrs, bool is_variadic) { SymbolFileDWARF *dwarf = die.GetDWARF(); @@ -1318,9 +1318,9 @@ DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die, if (attrs.name) { bool type_handled = false; if (tag == DW_TAG_subprogram || tag == DW_TAG_inlined_subroutine) { - if (std::optional<const ObjCLanguage::MethodName> objc_method = - ObjCLanguage::MethodName::Create(attrs.name.GetStringRef(), - true)) { + if (std::optional<const ObjCLanguage::ObjCMethodName> objc_method = + ObjCLanguage::ObjCMethodName::Create(attrs.name.GetStringRef(), + true)) { type_handled = ParseObjCMethod(*objc_method, die, clang_type, attrs, is_variadic); } else if (is_cxx_method) { @@ -2753,16 +2753,16 @@ PropertyAttributes::PropertyAttributes(const DWARFDIE &die) { // Check if the property getter/setter were provided as full names. // We want basenames, so we extract them. if (prop_getter_name && prop_getter_name[0] == '-') { - std::optional<const ObjCLanguage::MethodName> prop_getter_method = - ObjCLanguage::MethodName::Create(prop_getter_name, true); + std::optional<const ObjCLanguage::ObjCMethodName> prop_getter_method = + ObjCLanguage::ObjCMethodName::Create(prop_getter_name, true); if (prop_getter_method) prop_getter_name = ConstString(prop_getter_method->GetSelector()).GetCString(); } if (prop_setter_name && prop_setter_name[0] == '-') { - std::optional<const ObjCLanguage::MethodName> prop_setter_method = - ObjCLanguage::MethodName::Create(prop_setter_name, true); + std::optional<const ObjCLanguage::ObjCMethodName> prop_setter_method = + ObjCLanguage::ObjCMethodName::Create(prop_setter_name, true); if (prop_setter_method) prop_setter_name = ConstString(prop_setter_method->GetSelector()).GetCString(); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h index 135dd06186c4b..3994726aa6b3e 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h @@ -449,7 +449,7 @@ class DWARFASTParserClang : public lldb_private::plugin::dwarf::DWARFASTParser { /// /// \returns true on success bool - ParseObjCMethod(const lldb_private::ObjCLanguage::MethodName &objc_method, + ParseObjCMethod(const lldb_private::ObjCLanguage::ObjCMethodName &objc_method, const lldb_private::plugin::dwarf::DWARFDIE &die, lldb_private::CompilerType clang_type, const ParsedDWARFTypeAttributes &attrs, bool is_variadic); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp index 047967a30d098..98066b4a32cbc 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp @@ -308,8 +308,8 @@ void ManualDWARFIndex::IndexUnitImpl(DWARFUnit &unit, bool is_objc_method = false; if (cu_language == eLanguageTypeObjC || cu_language == eLanguageTypeObjC_plus_plus) { - std::optional<const ObjCLanguage::MethodName> objc_method = - ObjCLanguage::MethodName::Create(name, true); + std::optional<const ObjCLanguage::ObjCMethodName> objc_method = + ObjCLanguage::ObjCMethodName::Create(name, true); if (objc_method) { is_objc_method = true; ConstString class_name_with_category( diff --git a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp index 352163ceaae9e..f1d98e780994d 100644 --- a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp +++ b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp @@ -14,6 +14,7 @@ #include "clang/Lex/Lexer.h" #include "Plugins/TypeSystem/Clang/TypeSystemClang.h" +#include "lldb/Core/Mangled.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" #include "lldb/Symbol/CompileUnit.h" @@ -53,7 +54,6 @@ #include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h" -#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" #include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h" #include "Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h" @@ -1279,7 +1279,7 @@ void SymbolFilePDB::CacheFunctionNames() { if (name.empty()) continue; - if (CPlusPlusLanguage::IsCPPMangledName(name.c_str())) { + if (Mangled::IsMangledName(name.c_str())) { // PDB public symbol has mangled name for its associated function. if (auto vm_addr = pub_sym_up->getVirtualAddress()) { if (auto it = addr_ids.find(vm_addr); it != addr_ids.end()) diff --git a/lldb/unittests/Core/CMakeLists.txt b/lldb/unittests/Core/CMakeLists.txt index dc9c0577aa546..97268b3dbf8f8 100644 --- a/lldb/unittests/Core/CMakeLists.txt +++ b/lldb/unittests/Core/CMakeLists.txt @@ -19,6 +19,7 @@ add_lldb_unittest(LLDBCoreTests LINK_LIBS lldbCore lldbHost + lldbPluginCPlusPlusLanguage lldbPluginObjectFileELF lldbPluginObjectFileMachO lldbPluginObjectFilePECOFF diff --git a/lldb/unittests/Core/RichManglingContextTest.cpp b/lldb/unittests/Core/RichManglingContextTest.cpp index 65a5503c61a30..dfaea7efa3af0 100644 --- a/lldb/unittests/Core/RichManglingContextTest.cpp +++ b/lldb/unittests/Core/RichManglingContextTest.cpp @@ -8,6 +8,8 @@ #include "lldb/Core/RichManglingContext.h" +#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" +#include "TestingSupport/SubsystemRAII.h" #include "lldb/Utility/ConstString.h" #include "gtest/gtest.h" @@ -27,6 +29,9 @@ TEST(RichManglingContextTest, Basic) { } TEST(RichManglingContextTest, FromCxxMethodName) { + + SubsystemRAII<CPlusPlusLanguage> lang; + RichManglingContext ItaniumRMC; ConstString mangled("_ZN3foo3barEv"); EXPECT_TRUE(ItaniumRMC.FromItaniumName(mangled)); @@ -67,6 +72,8 @@ TEST(RichManglingContextTest, SwitchProvider) { EXPECT_TRUE(RMC.FromItaniumName(ConstString(mangled))); EXPECT_EQ("foo::bar()", RMC.ParseFullName()); + SubsystemRAII<CPlusPlusLanguage> lang; + EXPECT_TRUE(RMC.FromCxxMethodName(ConstString(demangled))); EXPECT_EQ("foo::bar()", RMC.ParseFullName()); diff --git a/lldb/unittests/Language/CPlusPlus/CPlusPlusLanguageTest.cpp b/lldb/unittests/Language/CPlusPlus/CPlusPlusLanguageTest.cpp index cfdc3163f6a3a..6eeb4f54952b9 100644 --- a/lldb/unittests/Language/CPlusPlus/CPlusPlusLanguageTest.cpp +++ b/lldb/unittests/Language/CPlusPlus/CPlusPlusLanguageTest.cpp @@ -212,7 +212,7 @@ TEST(CPlusPlusLanguage, MethodNameParsing) { "A::operator<=>[abi:tag]<A::B>"}}; for (const auto &test : test_cases) { - CPlusPlusLanguage::MethodName method(ConstString(test.input)); + CPlusPlusLanguage::CxxMethodName method(ConstString(test.input)); EXPECT_TRUE(method.IsValid()) << test.input; if (method.IsValid()) { EXPECT_EQ(test.return_type, method.GetReturnType().str()); @@ -243,22 +243,22 @@ TEST(CPlusPlusLanguage, InvalidMethodNameParsing) { }; for (const auto &name : test_cases) { - CPlusPlusLanguage::MethodName method{ConstString(name)}; + CPlusPlusLanguage::CxxMethodName method{ConstString(name)}; EXPECT_FALSE(method.IsValid()) << name; } } TEST(CPlusPlusLanguage, ContainsPath) { - CPlusPlusLanguage::MethodName - reference_1(ConstString("int foo::bar::func01(int a, double b)")); - CPlusPlusLanguage::MethodName - reference_2(ConstString("int foofoo::bar::func01(std::string a, int b)")); - CPlusPlusLanguage::MethodName reference_3(ConstString("int func01()")); - CPlusPlusLanguage::MethodName - reference_4(ConstString("bar::baz::operator bool()")); - CPlusPlusLanguage::MethodName reference_5( + CPlusPlusLanguage::CxxMethodName reference_1( + ConstString("int foo::bar::func01(int a, double b)")); + CPlusPlusLanguage::CxxMethodName reference_2( + ConstString("int foofoo::bar::func01(std::string a, int b)")); + CPlusPlusLanguage::CxxMethodName reference_3(ConstString("int func01()")); + CPlusPlusLanguage::CxxMethodName reference_4( + ConstString("bar::baz::operator bool()")); + CPlusPlusLanguage::CxxMethodName reference_5( ConstString("bar::baz::operator bool<int, Type<double>>()")); - CPlusPlusLanguage::MethodName reference_6(ConstString( + CPlusPlusLanguage::CxxMethodName reference_6(ConstString( "bar::baz::operator<<<Type<double>, Type<std::vector<double>>>()")); EXPECT_TRUE(reference_1.ContainsPath("")); diff --git a/lldb/unittests/Language/ObjC/ObjCLanguageTest.cpp b/lldb/unittests/Language/ObjC/ObjCLanguageTest.cpp index 59cc51b6ce08c..70baa7e6bc135 100644 --- a/lldb/unittests/Language/ObjC/ObjCLanguageTest.cpp +++ b/lldb/unittests/Language/ObjC/ObjCLanguageTest.cpp @@ -42,8 +42,8 @@ TEST(ObjCLanguage, MethodNameParsing) { // First, be strict for (const auto &test : strict_cases) { - std::optional<const ObjCLanguage::MethodName> method = - ObjCLanguage::MethodName::Create(test.input, /*strict = */ true); + std::optional<const ObjCLanguage::ObjCMethodName> method = + ObjCLanguage::ObjCMethodName::Create(test.input, /*strict = */ true); EXPECT_TRUE(method.has_value()); EXPECT_EQ(test.full_name_sans_category, method->GetFullNameWithoutCategory()); @@ -56,15 +56,15 @@ TEST(ObjCLanguage, MethodNameParsing) { // We should make sure strict parsing does not accept lax cases for (const auto &test : lax_cases) { - std::optional<const ObjCLanguage::MethodName> method = - ObjCLanguage::MethodName::Create(test.input, /*strict = */ true); + std::optional<const ObjCLanguage::ObjCMethodName> method = + ObjCLanguage::ObjCMethodName::Create(test.input, /*strict = */ true); EXPECT_FALSE(method.has_value()); } // All strict cases should work when not lax for (const auto &test : strict_cases) { - std::optional<const ObjCLanguage::MethodName> method = - ObjCLanguage::MethodName::Create(test.input, /*strict = */ false); + std::optional<const ObjCLanguage::ObjCMethodName> method = + ObjCLanguage::ObjCMethodName::Create(test.input, /*strict = */ false); EXPECT_TRUE(method.has_value()); EXPECT_EQ(test.full_name_sans_category, method->GetFullNameWithoutCategory()); @@ -77,8 +77,8 @@ TEST(ObjCLanguage, MethodNameParsing) { // Make sure non-strict parsing works for (const auto &test : lax_cases) { - std::optional<const ObjCLanguage::MethodName> method = - ObjCLanguage::MethodName::Create(test.input, /*strict = */ false); + std::optional<const ObjCLanguage::ObjCMethodName> method = + ObjCLanguage::ObjCMethodName::Create(test.input, /*strict = */ false); EXPECT_TRUE(method.has_value()); EXPECT_EQ(test.full_name_sans_category, method->GetFullNameWithoutCategory()); @@ -103,12 +103,12 @@ TEST(ObjCLanguage, InvalidMethodNameParsing) { "[]"}; for (const auto &name : test_cases) { - std::optional<const ObjCLanguage::MethodName> strict_method = - ObjCLanguage::MethodName::Create(name, /*strict = */ false); + std::optional<const ObjCLanguage::ObjCMethodName> strict_method = + ObjCLanguage::ObjCMethodName::Create(name, /*strict = */ false); EXPECT_FALSE(strict_method.has_value()); - std::optional<const ObjCLanguage::MethodName> lax_method = - ObjCLanguage::MethodName::Create(name, /*strict = */ false); + std::optional<const ObjCLanguage::ObjCMethodName> lax_method = + ObjCLanguage::ObjCMethodName::Create(name, /*strict = */ false); EXPECT_FALSE(lax_method.has_value()); } } _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits