[Lldb-commits] [lldb] dee9c7f - [NFCI] Simplify TypeCategoryImpl for-each callbacks.

Jorge Gorbe Moya via lldb-commits lldb-commits at lists.llvm.org
Thu Oct 6 12:11:53 PDT 2022


Author: Jorge Gorbe Moya
Date: 2022-10-06T12:11:27-07:00
New Revision: dee9c7f5d7e53aa6a9e7f85cdf9935341ba7e636

URL: https://github.com/llvm/llvm-project/commit/dee9c7f5d7e53aa6a9e7f85cdf9935341ba7e636
DIFF: https://github.com/llvm/llvm-project/commit/dee9c7f5d7e53aa6a9e7f85cdf9935341ba7e636.diff

LOG: [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

Added: 
    

Modified: 
    lldb/include/lldb/DataFormatters/TypeCategory.h
    lldb/source/Commands/CommandObjectType.cpp

Removed: 
    


################################################################################
diff  --git a/lldb/include/lldb/DataFormatters/TypeCategory.h b/lldb/include/lldb/DataFormatters/TypeCategory.h
index 2f0cb6c78472f..edf3f5d6605e4 100644
--- a/lldb/include/lldb/DataFormatters/TypeCategory.h
+++ b/lldb/include/lldb/DataFormatters/TypeCategory.h
@@ -130,6 +130,16 @@ template <typename FormatterImpl> class TieredFormatterContainer {
     return lldb::TypeNameSpecifierImplSP();
   }
 
+  /// Iterates through tiers in order, running `callback` on each element of
+  /// each tier.
+  void ForEach(std::function<bool(const TypeMatcher &,
+                                  const std::shared_ptr<FormatterImpl> &)>
+                   callback) {
+    for (auto sc : m_subcontainers) {
+      sc->ForEach(callback);
+    }
+  }
+
  private:
   std::array<std::shared_ptr<Subcontainer>, lldb::eLastFormatterMatchType + 1>
       m_subcontainers;
@@ -146,120 +156,36 @@ class TypeCategoryImpl {
   typedef uint16_t FormatCategoryItems;
   static const uint16_t ALL_ITEM_TYPES = UINT16_MAX;
 
-  template <typename T> class ForEachCallbacks {
-  public:
-    ForEachCallbacks() = default;
-    ~ForEachCallbacks() = default;
-
-    template <typename U = TypeFormatImpl>
-    typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type
-    SetExact(FormatContainer::ForEachCallback callback) {
-      m_format_exact = std::move(callback);
-      return *this;
-    }
-    template <typename U = TypeFormatImpl>
-    typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type
-    SetWithRegex(FormatContainer::ForEachCallback callback) {
-      m_format_regex = std::move(callback);
-      return *this;
-    }
-
-    template <typename U = TypeSummaryImpl>
-    typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type
-    SetExact(SummaryContainer::ForEachCallback callback) {
-      m_summary_exact = std::move(callback);
-      return *this;
-    }
-    template <typename U = TypeSummaryImpl>
-    typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type
-    SetWithRegex(SummaryContainer::ForEachCallback callback) {
-      m_summary_regex = std::move(callback);
-      return *this;
-    }
-
-    template <typename U = TypeFilterImpl>
-    typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type
-    SetExact(FilterContainer::ForEachCallback callback) {
-      m_filter_exact = std::move(callback);
-      return *this;
-    }
-    template <typename U = TypeFilterImpl>
-    typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type
-    SetWithRegex(FilterContainer::ForEachCallback callback) {
-      m_filter_regex = std::move(callback);
-      return *this;
-    }
-
-    template <typename U = SyntheticChildren>
-    typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type
-    SetExact(SynthContainer::ForEachCallback callback) {
-      m_synth_exact = std::move(callback);
-      return *this;
-    }
-    template <typename U = SyntheticChildren>
-    typename std::enable_if<std::is_same<U, T>::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<typename T>
+  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<TypeFormatImpl> callback = [](...) {...};
+    template <typename Callable> ForEachCallback(Callable c) : callback(c) {}
+    std::function<bool(const TypeMatcher &, const std::shared_ptr<T> &)>
+        callback;
   };
 
   TypeCategoryImpl(IFormatChangeListener *clist, ConstString name);
 
-  template <typename T> void ForEach(const ForEachCallbacks<T> &foreach) {
-    GetTypeFormatsContainer()->ForEach(foreach.GetFormatExactCallback());
-    GetRegexTypeFormatsContainer()->ForEach(foreach.GetFormatRegexCallback());
+  void ForEach(ForEachCallback<TypeFormatImpl> callback) {
+    m_format_cont.ForEach(callback.callback);
+  }
 
-    GetTypeSummariesContainer()->ForEach(foreach.GetSummaryExactCallback());
-    GetRegexTypeSummariesContainer()->ForEach(
-        foreach.GetSummaryRegexCallback());
+  void ForEach(ForEachCallback<TypeSummaryImpl> callback) {
+    m_summary_cont.ForEach(callback.callback);
+  }
 
-    GetTypeFiltersContainer()->ForEach(foreach.GetFilterExactCallback());
-    GetRegexTypeFiltersContainer()->ForEach(foreach.GetFilterRegexCallback());
+  void ForEach(ForEachCallback<TypeFilterImpl> callback) {
+    m_filter_cont.ForEach(callback.callback);
+  }
 
-    GetTypeSyntheticsContainer()->ForEach(foreach.GetSynthExactCallback());
-    GetRegexTypeSyntheticsContainer()->ForEach(foreach.GetSynthRegexCallback());
+  void ForEach(ForEachCallback<SyntheticChildren> 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 a285835aa277e..b78f98ce132bd 100644
--- a/lldb/source/Commands/CommandObjectType.cpp
+++ b/lldb/source/Commands/CommandObjectType.cpp
@@ -1097,36 +1097,20 @@ class CommandObjectTypeFormatterList : public CommandObjectParsed {
           "-----------------------\nCategory: %s%s\n-----------------------\n",
           category->GetName(), category->IsEnabled() ? "" : " (disabled)");
 
-      TypeCategoryImpl::ForEachCallbacks<FormatterType> 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<FormatterType> 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()) {


        


More information about the lldb-commits mailing list