Data formatter candidate matches can be generated in a number of ways; language-based dynamic type discovery being one of them (for instance, this is what takes an 'id' and discovers that it truly is an __NSArrayI, so it should probably use the NSArray formatter)

This used to be hardcoded in the FormatManager, but in a pluginized world that is not the right way to go

So, move this step to the Language plugin such that appropriate language plugins for a type get a say about adding candidates to the formatters lookup tables

llvm-svn: 247112
diff --git a/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp b/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp
index 3f37050..d6a68af 100644
--- a/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp
+++ b/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp
@@ -12,6 +12,9 @@
 #include "lldb/Core/ConstString.h"
 #include "lldb/Core/PluginManager.h"
 #include "lldb/Core/StreamString.h"
+#include "lldb/Core/ValueObject.h"
+#include "lldb/Symbol/CompilerType.h"
+#include "lldb/Target/ObjCLanguageRuntime.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -298,3 +301,37 @@
     }
     return names.size();
 }
+
+std::vector<ConstString>
+ObjCLanguage::GetPossibleFormattersMatches (ValueObject& valobj, lldb::DynamicValueType use_dynamic)
+{
+    std::vector<ConstString> result;
+    
+    if (use_dynamic == lldb::eNoDynamicValues)
+        return result;
+    
+    CompilerType compiler_type(valobj.GetCompilerType());
+    
+    const bool check_cpp = false;
+    const bool check_objc = true;
+    bool canBeObjCDynamic = compiler_type.IsPossibleDynamicType(nullptr, check_cpp, check_objc);
+    
+    if (canBeObjCDynamic)
+    {
+        do {
+            lldb::ProcessSP process_sp = valobj.GetProcessSP();
+            if (!process_sp)
+                break;
+            ObjCLanguageRuntime* runtime = process_sp->GetObjCLanguageRuntime();
+            if (runtime == nullptr)
+                break;
+            ObjCLanguageRuntime::ClassDescriptorSP objc_class_sp (runtime->GetClassDescriptor(valobj));
+            if (!objc_class_sp)
+                break;
+            if (ConstString name = objc_class_sp->GetClassName())
+                result.push_back(name);
+        } while (false);
+    }
+    
+    return result;
+}
diff --git a/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h b/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h
index 9c69fbf..3850c21 100644
--- a/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h
+++ b/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h
@@ -135,11 +135,14 @@
     ObjCLanguage () = default;
     
     lldb::LanguageType
-    GetLanguageType () const
+    GetLanguageType () const override
     {
         return lldb::eLanguageTypeObjC;
     }
     
+    std::vector<ConstString>
+    GetPossibleFormattersMatches (ValueObject& valobj, lldb::DynamicValueType use_dynamic) override;
+    
     //------------------------------------------------------------------
     // Static Functions
     //------------------------------------------------------------------
@@ -183,10 +186,10 @@
     // PluginInterface protocol
     //------------------------------------------------------------------
     virtual ConstString
-    GetPluginName();
+    GetPluginName() override;
     
     virtual uint32_t
-    GetPluginVersion();
+    GetPluginVersion() override;
 };
     
 } // namespace lldb_private