https://github.com/slydiman updated 
https://github.com/llvm/llvm-project/pull/135033

>From 5e365a86734b33f4ce31eb9199b88a4a772b5342 Mon Sep 17 00:00:00 2001
From: Dmitry Vasilyev <dvassil...@accesssoftek.com>
Date: Wed, 9 Apr 2025 17:06:49 +0400
Subject: [PATCH] [LLDB] Reapply refactored CPlusPlusLanguage::MethodName to
 break lldb-server dependencies

The original PR is #132274.

Co-authored-by: @bulbazord Alex Langford
---
 lldb/include/lldb/Core/Mangled.h              |   2 +
 lldb/include/lldb/Core/RichManglingContext.h  |  16 +-
 lldb/include/lldb/Target/Language.h           |  98 ++++++++++++
 lldb/source/Core/CMakeLists.txt               |   5 +-
 lldb/source/Core/Mangled.cpp                  |  12 +-
 lldb/source/Core/Module.cpp                   | 151 +++++++-----------
 lldb/source/Core/RichManglingContext.cpp      |  22 ++-
 .../Clang/ClangExpressionDeclMap.cpp          |  11 +-
 .../Language/CPlusPlus/CPlusPlusLanguage.cpp  | 131 +++++++--------
 .../Language/CPlusPlus/CPlusPlusLanguage.h    |  62 ++-----
 .../Plugins/Language/ObjC/ObjCLanguage.cpp    |  33 ++--
 .../Plugins/Language/ObjC/ObjCLanguage.h      |  15 +-
 .../SymbolFile/DWARF/DWARFASTParserClang.cpp  |  16 +-
 .../SymbolFile/DWARF/DWARFASTParserClang.h    |   2 +-
 .../SymbolFile/DWARF/ManualDWARFIndex.cpp     |   4 +-
 .../Plugins/SymbolFile/PDB/SymbolFilePDB.cpp  |   4 +-
 lldb/unittests/Core/CMakeLists.txt            |   1 +
 .../Core/RichManglingContextTest.cpp          |   7 +
 .../CPlusPlus/CPlusPlusLanguageTest.cpp       |  22 +--
 .../Language/ObjC/ObjCLanguageTest.cpp        |  24 +--
 20 files changed, 328 insertions(+), 310 deletions(-)

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 b699a90aff8e4..b96a6ab3d8b45 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 4b045d12ad494..ab0b9548ce706 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 623d481bf117f..3a222c8d76de9 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 8580f5887ea2b..2c97a0fd815c5 100644
--- a/lldb/unittests/Core/CMakeLists.txt
+++ b/lldb/unittests/Core/CMakeLists.txt
@@ -18,6 +18,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

Reply via email to