From dee9c7f5d7e53aa6a9e7f85cdf9935341ba7e636 Mon Sep 17 00:00:00 2001 From: Jorge Gorbe Moya Date: Fri, 16 Sep 2022 15:58:19 -0700 Subject: [PATCH] [NFCI] Simplify TypeCategoryImpl for-each callbacks. The callback system to iterate over every formatter of a given kind in a TypeCategoryImpl is only used in one place (the implementation of `type {formatter_kind} list`), and it's too convoluted for the sake of unused flexibility. This change changes it so that only one callback is passed to `ForEach` (instead of a callback for exact matches and another one for regex matches), and moves the iteration logic to `TieredFormatterContainer` to avoid duplication. If in the future we need different logic in the callback depending on exact/regex match, the callback can get the type of formatter matching used from the TypeMatcher argument anyway. Differential Revision: https://reviews.llvm.org/D134771 --- lldb/include/lldb/DataFormatters/TypeCategory.h | 140 ++++++------------------ lldb/source/Commands/CommandObjectType.cpp | 44 +++----- 2 files changed, 47 insertions(+), 137 deletions(-) diff --git a/lldb/include/lldb/DataFormatters/TypeCategory.h b/lldb/include/lldb/DataFormatters/TypeCategory.h index 2f0cb6c..edf3f5d 100644 --- a/lldb/include/lldb/DataFormatters/TypeCategory.h +++ b/lldb/include/lldb/DataFormatters/TypeCategory.h @@ -130,6 +130,16 @@ public: return lldb::TypeNameSpecifierImplSP(); } + /// Iterates through tiers in order, running `callback` on each element of + /// each tier. + void ForEach(std::function &)> + callback) { + for (auto sc : m_subcontainers) { + sc->ForEach(callback); + } + } + private: std::array, lldb::eLastFormatterMatchType + 1> m_subcontainers; @@ -146,120 +156,36 @@ public: 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() { diff --git a/lldb/source/Commands/CommandObjectType.cpp b/lldb/source/Commands/CommandObjectType.cpp index a285835..b78f98c 100644 --- a/lldb/source/Commands/CommandObjectType.cpp +++ b/lldb/source/Commands/CommandObjectType.cpp @@ -1097,36 +1097,20 @@ protected: "-----------------------\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()) { -- 2.7.4