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
This commit is contained in:
Enrico Granata 2015-09-09 01:10:46 +00:00
parent 1ef6e4c870
commit d3233c1ed7
7 changed files with 83 additions and 50 deletions

View File

@ -264,6 +264,9 @@ public:
private:
static std::vector<lldb::LanguageType>
GetCandidateLanguages (ValueObject& valobj);
static void
GetPossibleMatches (ValueObject& valobj,
CompilerType clang_type,

View File

@ -13,6 +13,7 @@
// C Includes
// C++ Includes
#include <functional>
#include <vector>
// Other libraries and framework includes
// Project includes
@ -22,11 +23,10 @@
namespace lldb_private {
class Language :
public PluginInterface
{
public:
class Language :
public PluginInterface
{
public:
~Language() override;
static Language*
@ -42,6 +42,9 @@ namespace lldb_private {
virtual lldb::TypeCategoryImplSP
GetFormatters ();
virtual std::vector<ConstString>
GetPossibleFormattersMatches (ValueObject& valobj, lldb::DynamicValueType use_dynamic);
// These are accessors for general information about the Languages lldb knows about:
static lldb::LanguageType
@ -70,16 +73,16 @@ namespace lldb_private {
LanguageIsPascal (lldb::LanguageType language);
protected:
//------------------------------------------------------------------
// Classes that inherit from Language can see and modify these
//------------------------------------------------------------------
Language();
private:
DISALLOW_COPY_AND_ASSIGN (Language);
};
protected:
//------------------------------------------------------------------
// Classes that inherit from Language can see and modify these
//------------------------------------------------------------------
Language();
private:
DISALLOW_COPY_AND_ASSIGN (Language);
};
} // namespace lldb_private

View File

@ -188,7 +188,7 @@ typedef enum FormatterChoiceCriterion
eFormatterChoiceCriterionNavigatedTypedefs = 0x00000002,
eFormatterChoiceCriterionRegularExpressionSummary = 0x00000004,
eFormatterChoiceCriterionRegularExpressionFilter = 0x00000004,
eFormatterChoiceCriterionDynamicObjCDiscovery = 0x00000008,
eFormatterChoiceCriterionLanguagePlugin = 0x00000008,
eFormatterChoiceCriterionStrippedBitField = 0x00000010,
eFormatterChoiceCriterionWentToStaticValue = 0x00000020
} FormatterChoiceCriterion;

View File

@ -270,41 +270,22 @@ FormatManager::GetPossibleMatches (ValueObject& valobj,
true); // this is not exactly the usual meaning of stripping typedefs
}
}
bool canBeObjCDynamic = clang_type.IsPossibleDynamicType (NULL,
false, // no C
true); // yes ObjC
if (canBeObjCDynamic)
for (lldb::LanguageType language_type : GetCandidateLanguages(valobj))
{
if (use_dynamic != lldb::eNoDynamicValues)
if (Language* language = Language::FindPlugin(language_type))
{
do
for (ConstString candidate : language->GetPossibleFormattersMatches(valobj, use_dynamic))
{
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;
ConstString name (objc_class_sp->GetClassName());
entries.push_back({name,reason | lldb_private::eFormatterChoiceCriterionDynamicObjCDiscovery,did_strip_ptr,did_strip_ref,did_strip_typedef});
} while (false);
entries.push_back({candidate,
reason | lldb_private::eFormatterChoiceCriterionLanguagePlugin,
did_strip_ptr,
did_strip_ref,
did_strip_typedef});
}
}
CompilerType non_ptr_type = clang_type.GetPointeeType();
GetPossibleMatches(valobj,
non_ptr_type,
reason | lldb_private::eFormatterChoiceCriterionStrippedPointerReference,
use_dynamic,
entries,
true,
did_strip_ref,
did_strip_typedef);
}
// try to strip typedef chains
if (clang_type.IsTypedefType())
{
@ -666,8 +647,8 @@ FormatManager::GetTypeForCache (ValueObject& valobj,
return ConstString();
}
static std::vector<lldb::LanguageType>
GetCandidateLanguages (ValueObject& valobj)
std::vector<lldb::LanguageType>
FormatManager::GetCandidateLanguages (ValueObject& valobj)
{
lldb::LanguageType lang_type = valobj.GetObjectRuntimeLanguage();
switch (lang_type)

View File

@ -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 @@ ObjCLanguage::MethodName::GetFullNames (std::vector<ConstString> &names, bool ap
}
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;
}

View File

@ -135,11 +135,14 @@ public:
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 @@ public:
// PluginInterface protocol
//------------------------------------------------------------------
virtual ConstString
GetPluginName();
GetPluginName() override;
virtual uint32_t
GetPluginVersion();
GetPluginVersion() override;
};
} // namespace lldb_private

View File

@ -94,6 +94,12 @@ Language::GetFormatters ()
return nullptr;
}
std::vector<ConstString>
Language::GetPossibleFormattersMatches (ValueObject& valobj, lldb::DynamicValueType use_dynamic)
{
return {};
}
struct language_name_pair {
const char *name;
LanguageType type;