diff options
author | Enrico Granata <egranata@apple.com> | 2015-09-01 01:01:48 +0000 |
---|---|---|
committer | Enrico Granata <egranata@apple.com> | 2015-09-01 01:01:48 +0000 |
commit | 2233895a3b7fa414eb7a1e459ff1829170ea6b31 (patch) | |
tree | d4baaf4020acfb48e9a44f3a8b1ac7985c4c79a7 /lldb/source/DataFormatters/FormatManager.cpp | |
parent | 989364c10153a3b60260abb131295ee571c49117 (diff) | |
download | bcm5719-llvm-2233895a3b7fa414eb7a1e459ff1829170ea6b31.tar.gz bcm5719-llvm-2233895a3b7fa414eb7a1e459ff1829170ea6b31.zip |
Add support for language plugins to provide data formatters
Historically, data formatters all exist in a global repository (the category map)
On top of that, some formatters can be "hardcoded" when the conditions under which they apply are not expressible as a typename (or typename regex)
This change paves the way to move formatters into per-language buckets such that the C++ plugin is responsible for ownership of the C++ formatters, and so on
The advantages of this are:
a) language formatters only get created when they might apply
b) formatters for a language are clearly owned by the matching language plugin
The current model is one of static instantiation, that is a language knows the full set of formatters it vends and that is only asked-for once, and then handed off to the FormatManager
In a future revision it might be interesting to add similar ability to the language runtimes, and monitor for certain shared library events to add even more library-specific formatters
No formatters are moved as part of this change, so practically speaking this is NFC
llvm-svn: 246515
Diffstat (limited to 'lldb/source/DataFormatters/FormatManager.cpp')
-rw-r--r-- | lldb/source/DataFormatters/FormatManager.cpp | 150 |
1 files changed, 134 insertions, 16 deletions
diff --git a/lldb/source/DataFormatters/FormatManager.cpp b/lldb/source/DataFormatters/FormatManager.cpp index e41d341a21e..52209cae3be 100644 --- a/lldb/source/DataFormatters/FormatManager.cpp +++ b/lldb/source/DataFormatters/FormatManager.cpp @@ -16,10 +16,13 @@ #include "lldb/Core/Debugger.h" #include "lldb/DataFormatters/CXXFormatterFunctions.h" +#include "lldb/DataFormatters/LanguageCategory.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Platform.h" #include "llvm/ADT/STLExtras.h" +#include <initializer_list> + using namespace lldb; using namespace lldb_private; @@ -472,6 +475,20 @@ FormatManager::GetValidatorForType (lldb::TypeNameSpecifierImplSP type_sp) return validator_chosen_sp; } +void +FormatManager::LoopThroughCategories (CategoryCallback callback, void* param) +{ + m_categories_map.LoopThrough(callback, param); + for (const auto& entry : m_language_categories_map) + { + if (auto category_sp = entry.second->GetCategory()) + { + if (!callback(param, category_sp)) + break; + } + } +} + lldb::TypeCategoryImplSP FormatManager::GetCategory (const ConstString& category_name, bool can_create) @@ -596,8 +613,8 @@ FormatManager::GetValidTypeName (const ConstString& type) } ConstString -GetTypeForCache (ValueObject& valobj, - lldb::DynamicValueType use_dynamic) +FormatManager::GetTypeForCache (ValueObject& valobj, + lldb::DynamicValueType use_dynamic) { if (use_dynamic == lldb::eNoDynamicValues) { @@ -618,6 +635,28 @@ GetTypeForCache (ValueObject& valobj, return ConstString(); } +static std::initializer_list<lldb::LanguageType> +GetCandidateLanguages (ValueObject& valobj) +{ + lldb::LanguageType lang_type = valobj.GetObjectRuntimeLanguage(); + switch (lang_type) + { + default: + return {lang_type}; + } +} + +LanguageCategory* +FormatManager::GetCategoryForLanguage (lldb::LanguageType lang_type) +{ + auto iter = m_language_categories_map.find(lang_type), end = m_language_categories_map.end(); + if (iter != end) + return iter->second.get(); + LanguageCategory* lang_category = new LanguageCategory(lang_type); + m_language_categories_map[lang_type] = LanguageCategory::UniquePointer(lang_category); + return lang_category; +} + lldb::TypeFormatImplSP FormatManager::GetHardcodedFormat (ValueObject& valobj, lldb::DynamicValueType use_dynamic) @@ -655,7 +694,29 @@ FormatManager::GetFormat (ValueObject& valobj, if (log) log->Printf("[FormatManager::GetFormat] Cache search failed. Going normal route"); } - retval = m_categories_map.GetFormat(valobj, use_dynamic); + + FormattersMatchVector matches = GetPossibleMatches(valobj, use_dynamic); + + retval = m_categories_map.GetFormat(valobj, use_dynamic, matches); + if (!retval) + { + if (log) + log->Printf("[FormatManager::GetFormat] Search failed. Giving language a chance."); + for (lldb::LanguageType lang_type : GetCandidateLanguages(valobj)) + { + if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type)) + { + if (lang_category->Get(valobj, use_dynamic, matches, retval)) + break; + } + } + if (retval) + { + if (log) + log->Printf("[FormatManager::GetFormat] Language search success. Returning."); + return retval; + } + } if (!retval) { if (log) @@ -713,7 +774,29 @@ FormatManager::GetSummaryFormat (ValueObject& valobj, if (log) log->Printf("[FormatManager::GetSummaryFormat] Cache search failed. Going normal route"); } - retval = m_categories_map.GetSummaryFormat(valobj, use_dynamic); + + FormattersMatchVector matches = GetPossibleMatches(valobj, use_dynamic); + + retval = m_categories_map.GetSummaryFormat(valobj, use_dynamic, matches); + if (!retval) + { + if (log) + log->Printf("[FormatManager::GetSummaryFormat] Search failed. Giving language a chance."); + for (lldb::LanguageType lang_type : GetCandidateLanguages(valobj)) + { + if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type)) + { + if (lang_category->Get(valobj, use_dynamic, matches, retval)) + break; + } + } + if (retval) + { + if (log) + log->Printf("[FormatManager::GetSummaryFormat] Language search success. Returning."); + return retval; + } + } if (!retval) { if (log) @@ -772,7 +855,29 @@ FormatManager::GetSyntheticChildren (ValueObject& valobj, if (log) log->Printf("[FormatManager::GetSyntheticChildren] Cache search failed. Going normal route"); } - retval = m_categories_map.GetSyntheticChildren(valobj, use_dynamic); + + FormattersMatchVector matches = GetPossibleMatches(valobj, use_dynamic); + + retval = m_categories_map.GetSyntheticChildren(valobj, use_dynamic, matches); + if (!retval) + { + if (log) + log->Printf("[FormatManager::GetSyntheticChildren] Search failed. Giving language a chance."); + for (lldb::LanguageType lang_type : GetCandidateLanguages(valobj)) + { + if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type)) + { + if (lang_category->Get(valobj, use_dynamic, matches, retval)) + break; + } + } + if (retval) + { + if (log) + log->Printf("[FormatManager::GetSyntheticChildren] Language search success. Returning."); + return retval; + } + } if (!retval) { if (log) @@ -818,7 +923,29 @@ FormatManager::GetValidator (ValueObject& valobj, if (log) log->Printf("[FormatManager::GetValidator] Cache search failed. Going normal route"); } - retval = m_categories_map.GetValidator(valobj, use_dynamic); + + FormattersMatchVector matches = GetPossibleMatches(valobj, use_dynamic); + + retval = m_categories_map.GetValidator(valobj, use_dynamic, matches); + if (!retval) + { + if (log) + log->Printf("[FormatManager::GetValidator] Search failed. Giving language a chance."); + for (lldb::LanguageType lang_type : GetCandidateLanguages(valobj)) + { + if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type)) + { + if (lang_category->Get(valobj, use_dynamic, matches, retval)) + break; + } + } + if (retval) + { + if (log) + log->Printf("[FormatManager::GetValidator] Language search success. Returning."); + return retval; + } + } if (!retval) { if (log) @@ -857,6 +984,7 @@ FormatManager::FormatManager() : m_named_summaries_map(this), m_last_revision(0), m_categories_map(this), + m_language_categories_map(), m_default_category_name(ConstString("default")), m_system_category_name(ConstString("system")), m_gnu_cpp_category_name(ConstString("gnu-libstdc++")), @@ -1083,17 +1211,7 @@ FormatManager::LoadLibcxxFormatters() lldb::TypeSummaryImplSP std_wstring_summary_sp(new CXXFunctionSummaryFormat(stl_summary_flags, lldb_private::formatters::LibcxxWStringSummaryProvider, "std::wstring summary provider")); TypeCategoryImpl::SharedPointer libcxx_category_sp = GetCategory(m_libcxx_category_name); - - libcxx_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::__1::string"), - std_string_summary_sp); - libcxx_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >"), - std_string_summary_sp); - libcxx_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::__1::wstring"), - std_wstring_summary_sp); - libcxx_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >"), - std_wstring_summary_sp); - SyntheticChildren::Flags stl_synth_flags; stl_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(false); |