Index: lldb/include/lldb/DataFormatters/TypeCategory.h =================================================================== --- lldb/include/lldb/DataFormatters/TypeCategory.h +++ lldb/include/lldb/DataFormatters/TypeCategory.h @@ -130,6 +130,16 @@ return lldb::TypeNameSpecifierImplSP(); } + /// Iterates through tiers in order, running `callback` on each element of + /// each tier. + void ForEach(std::function)> + callback) { + for (int tier = 0; tier <= lldb::eLastFormatterMatchType; ++tier) { + m_subcontainers[tier]->ForEach(callback); + } + } + private: std::array, lldb::eLastFormatterMatchType + 1> m_subcontainers; @@ -146,120 +156,35 @@ typedef uint16_t FormatCategoryItems; static const uint16_t ALL_ITEM_TYPES = UINT16_MAX; - template class ForEachCallbacks { - public: - ForEachCallbacks() = default; - ~ForEachCallbacks() = default; - - template - typename std::enable_if::value, ForEachCallbacks &>::type - SetExact(FormatContainer::ForEachCallback callback) { - m_format_exact = std::move(callback); - return *this; - } - template - typename std::enable_if::value, ForEachCallbacks &>::type - SetWithRegex(FormatContainer::ForEachCallback callback) { - m_format_regex = std::move(callback); - return *this; - } - - template - typename std::enable_if::value, ForEachCallbacks &>::type - SetExact(SummaryContainer::ForEachCallback callback) { - m_summary_exact = std::move(callback); - return *this; - } - template - typename std::enable_if::value, ForEachCallbacks &>::type - SetWithRegex(SummaryContainer::ForEachCallback callback) { - m_summary_regex = std::move(callback); - return *this; - } - - template - typename std::enable_if::value, ForEachCallbacks &>::type - SetExact(FilterContainer::ForEachCallback callback) { - m_filter_exact = std::move(callback); - return *this; - } - template - typename std::enable_if::value, ForEachCallbacks &>::type - SetWithRegex(FilterContainer::ForEachCallback callback) { - m_filter_regex = std::move(callback); - return *this; - } - - template - typename std::enable_if::value, ForEachCallbacks &>::type - SetExact(SynthContainer::ForEachCallback callback) { - m_synth_exact = std::move(callback); - return *this; - } - template - typename std::enable_if::value, ForEachCallbacks &>::type - SetWithRegex(SynthContainer::ForEachCallback callback) { - m_synth_regex = std::move(callback); - return *this; - } - - FormatContainer::ForEachCallback GetFormatExactCallback() const { - return m_format_exact; - } - FormatContainer::ForEachCallback GetFormatRegexCallback() const { - return m_format_regex; - } - - SummaryContainer::ForEachCallback GetSummaryExactCallback() const { - return m_summary_exact; - } - SummaryContainer::ForEachCallback GetSummaryRegexCallback() const { - return m_summary_regex; - } - - FilterContainer::ForEachCallback GetFilterExactCallback() const { - return m_filter_exact; - } - FilterContainer::ForEachCallback GetFilterRegexCallback() const { - return m_filter_regex; - } - - SynthContainer::ForEachCallback GetSynthExactCallback() const { - return m_synth_exact; - } - SynthContainer::ForEachCallback GetSynthRegexCallback() const { - return m_synth_regex; - } - - private: - FormatContainer::ForEachCallback m_format_exact; - FormatContainer::ForEachCallback m_format_regex; - - SummaryContainer::ForEachCallback m_summary_exact; - SummaryContainer::ForEachCallback m_summary_regex; - - FilterContainer::ForEachCallback m_filter_exact; - FilterContainer::ForEachCallback m_filter_regex; - - SynthContainer::ForEachCallback m_synth_exact; - SynthContainer::ForEachCallback m_synth_regex; + // TypeFilterImpl inherits from SyntheticChildren, so we can't simply overload + // ForEach on the type of the callback because it would result in "call to + // member function 'ForEach' is ambiguous" errors. Instead we use this + // templated struct to hold the formatter type and the callback. + template + struct ForEachCallback { + // Make it constructible from any callable that fits. This allows us to use + // lambdas a bit more easily at the call site. For example: + // ForEachCallback callback = [](...) {...}; + template ForEachCallback(Callable c) : callback(c) {} + std::function)> callback; }; TypeCategoryImpl(IFormatChangeListener *clist, ConstString name); - template void ForEach(const ForEachCallbacks &foreach) { - GetTypeFormatsContainer()->ForEach(foreach.GetFormatExactCallback()); - GetRegexTypeFormatsContainer()->ForEach(foreach.GetFormatRegexCallback()); + void ForEach(ForEachCallback callback) { + m_format_cont.ForEach(callback.callback); + } - GetTypeSummariesContainer()->ForEach(foreach.GetSummaryExactCallback()); - GetRegexTypeSummariesContainer()->ForEach( - foreach.GetSummaryRegexCallback()); + void ForEach(ForEachCallback callback) { + m_summary_cont.ForEach(callback.callback); + } - GetTypeFiltersContainer()->ForEach(foreach.GetFilterExactCallback()); - GetRegexTypeFiltersContainer()->ForEach(foreach.GetFilterRegexCallback()); + void ForEach(ForEachCallback callback) { + m_filter_cont.ForEach(callback.callback); + } - GetTypeSyntheticsContainer()->ForEach(foreach.GetSynthExactCallback()); - GetRegexTypeSyntheticsContainer()->ForEach(foreach.GetSynthRegexCallback()); + void ForEach(ForEachCallback callback) { + m_synth_cont.ForEach(callback.callback); } FormatContainer::SubcontainerSP GetTypeFormatsContainer() { Index: lldb/source/Commands/CommandObjectType.cpp =================================================================== --- lldb/source/Commands/CommandObjectType.cpp +++ lldb/source/Commands/CommandObjectType.cpp @@ -1097,36 +1097,20 @@ "-----------------------\nCategory: %s%s\n-----------------------\n", category->GetName(), category->IsEnabled() ? "" : " (disabled)"); - TypeCategoryImpl::ForEachCallbacks foreach; - foreach - .SetExact([&result, &formatter_regex, &any_printed]( - const TypeMatcher &type_matcher, - const FormatterSharedPointer &format_sp) -> bool { - if (ShouldListItem(type_matcher.GetMatchString().GetStringRef(), - formatter_regex.get())) { - any_printed = true; - result.GetOutputStream().Printf( - "%s: %s\n", type_matcher.GetMatchString().GetCString(), - format_sp->GetDescription().c_str()); - } - return true; - }); - - foreach - .SetWithRegex([&result, &formatter_regex, &any_printed]( - const TypeMatcher &type_matcher, - const FormatterSharedPointer &format_sp) -> bool { - if (ShouldListItem(type_matcher.GetMatchString().GetStringRef(), - formatter_regex.get())) { - any_printed = true; - result.GetOutputStream().Printf( - "%s: %s\n", type_matcher.GetMatchString().GetCString(), - format_sp->GetDescription().c_str()); - } - return true; - }); - - category->ForEach(foreach); + TypeCategoryImpl::ForEachCallback print_formatter = + [&result, &formatter_regex, + &any_printed](const TypeMatcher &type_matcher, + const FormatterSharedPointer &format_sp) -> bool { + if (ShouldListItem(type_matcher.GetMatchString().GetStringRef(), + formatter_regex.get())) { + any_printed = true; + result.GetOutputStream().Printf( + "%s: %s\n", type_matcher.GetMatchString().GetCString(), + format_sp->GetDescription().c_str()); + } + return true; + }; + category->ForEach(print_formatter); }; if (m_options.m_category_language.OptionWasSet()) {