diff --git a/lldb/include/lldb/Target/Language.h b/lldb/include/lldb/Target/Language.h --- a/lldb/include/lldb/Target/Language.h +++ b/lldb/include/lldb/Target/Language.h @@ -192,6 +192,13 @@ return std::vector(); }; + /// Returns true iff the given symbol name is compatible with the mangling + /// scheme of this language. + /// + /// This function should only return true if there is a high confidence + /// that the name actually belongs to this language. + virtual bool SymbolNameFitsToLanguage(Mangled name) const { return false; } + // if an individual data formatter can apply to several types and cross a // language boundary it makes sense for individual languages to want to // customize the printing of values of that type by appending proper diff --git a/lldb/source/Core/Mangled.cpp b/lldb/source/Core/Mangled.cpp --- a/lldb/source/Core/Mangled.cpp +++ b/lldb/source/Core/Mangled.cpp @@ -17,7 +17,6 @@ #include "lldb/lldb-enumerations.h" #include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" -#include "Plugins/Language/ObjC/ObjCLanguage.h" #include "llvm/ADT/StringRef.h" #include "llvm/Demangle/Demangle.h" @@ -373,22 +372,16 @@ // of mangling names from a given language, likewise the compilation units // within those targets. lldb::LanguageType Mangled::GuessLanguage() const { - ConstString mangled = GetMangledName(); - - if (mangled) { - const char *mangled_name = mangled.GetCString(); - if (CPlusPlusLanguage::IsCPPMangledName(mangled_name)) - return lldb::eLanguageTypeC_plus_plus; - } else { - // ObjC names aren't really mangled, so they won't necessarily be in the - // mangled name slot. - ConstString demangled_name = GetDemangledName(); - if (demangled_name - && ObjCLanguage::IsPossibleObjCMethodName(demangled_name.GetCString())) - return lldb::eLanguageTypeObjC; - - } - return lldb::eLanguageTypeUnknown; + lldb::LanguageType result = lldb::eLanguageTypeUnknown; + // Ask each language plugin to check if the mangled name belongs to it. + Language::ForEach([this, &result](Language *l) { + if (l->SymbolNameFitsToLanguage(*this)) { + result = l->GetLanguageType(); + return false; + } + return true; + }); + return result; } // Dump OBJ to the supplied stream S. diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h --- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h +++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h @@ -105,6 +105,8 @@ static lldb_private::ConstString GetPluginNameStatic(); + bool SymbolNameFitsToLanguage(Mangled mangled) const override; + static bool IsCPPMangledName(llvm::StringRef name); // Extract C++ context and identifier from a string using heuristic matching diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp --- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp @@ -59,6 +59,11 @@ return g_name; } +bool CPlusPlusLanguage::SymbolNameFitsToLanguage(Mangled mangled) const { + const char *mangled_name = mangled.GetMangledName().GetCString(); + return mangled_name && CPlusPlusLanguage::IsCPPMangledName(mangled_name); +} + // PluginInterface protocol lldb_private::ConstString CPlusPlusLanguage::GetPluginName() { diff --git a/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h b/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h --- a/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h +++ b/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h @@ -105,6 +105,8 @@ std::vector GetMethodNameVariants(ConstString method_name) const override; + bool SymbolNameFitsToLanguage(Mangled mangled) const override; + lldb::TypeCategoryImplSP GetFormatters() override; std::vector diff --git a/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp b/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp --- a/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp +++ b/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp @@ -267,6 +267,13 @@ return variant_names; } +bool ObjCLanguage::SymbolNameFitsToLanguage(Mangled mangled) const { + ConstString demangled_name = mangled.GetDemangledName(); + if (!demangled_name) + return false; + return ObjCLanguage::IsPossibleObjCMethodName(demangled_name.GetCString()); +} + static void LoadObjCFormatters(TypeCategoryImplSP objc_category_sp) { if (!objc_category_sp) return;