Skip to content

Commit dee9c7f

Browse files
committed
[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
1 parent 323ed23 commit dee9c7f

File tree

2 files changed

+47
-137
lines changed

2 files changed

+47
-137
lines changed

lldb/include/lldb/DataFormatters/TypeCategory.h

Lines changed: 33 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,16 @@ template <typename FormatterImpl> class TieredFormatterContainer {
130130
return lldb::TypeNameSpecifierImplSP();
131131
}
132132

133+
/// Iterates through tiers in order, running `callback` on each element of
134+
/// each tier.
135+
void ForEach(std::function<bool(const TypeMatcher &,
136+
const std::shared_ptr<FormatterImpl> &)>
137+
callback) {
138+
for (auto sc : m_subcontainers) {
139+
sc->ForEach(callback);
140+
}
141+
}
142+
133143
private:
134144
std::array<std::shared_ptr<Subcontainer>, lldb::eLastFormatterMatchType + 1>
135145
m_subcontainers;
@@ -146,120 +156,36 @@ class TypeCategoryImpl {
146156
typedef uint16_t FormatCategoryItems;
147157
static const uint16_t ALL_ITEM_TYPES = UINT16_MAX;
148158

149-
template <typename T> class ForEachCallbacks {
150-
public:
151-
ForEachCallbacks() = default;
152-
~ForEachCallbacks() = default;
153-
154-
template <typename U = TypeFormatImpl>
155-
typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type
156-
SetExact(FormatContainer::ForEachCallback callback) {
157-
m_format_exact = std::move(callback);
158-
return *this;
159-
}
160-
template <typename U = TypeFormatImpl>
161-
typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type
162-
SetWithRegex(FormatContainer::ForEachCallback callback) {
163-
m_format_regex = std::move(callback);
164-
return *this;
165-
}
166-
167-
template <typename U = TypeSummaryImpl>
168-
typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type
169-
SetExact(SummaryContainer::ForEachCallback callback) {
170-
m_summary_exact = std::move(callback);
171-
return *this;
172-
}
173-
template <typename U = TypeSummaryImpl>
174-
typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type
175-
SetWithRegex(SummaryContainer::ForEachCallback callback) {
176-
m_summary_regex = std::move(callback);
177-
return *this;
178-
}
179-
180-
template <typename U = TypeFilterImpl>
181-
typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type
182-
SetExact(FilterContainer::ForEachCallback callback) {
183-
m_filter_exact = std::move(callback);
184-
return *this;
185-
}
186-
template <typename U = TypeFilterImpl>
187-
typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type
188-
SetWithRegex(FilterContainer::ForEachCallback callback) {
189-
m_filter_regex = std::move(callback);
190-
return *this;
191-
}
192-
193-
template <typename U = SyntheticChildren>
194-
typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type
195-
SetExact(SynthContainer::ForEachCallback callback) {
196-
m_synth_exact = std::move(callback);
197-
return *this;
198-
}
199-
template <typename U = SyntheticChildren>
200-
typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type
201-
SetWithRegex(SynthContainer::ForEachCallback callback) {
202-
m_synth_regex = std::move(callback);
203-
return *this;
204-
}
205-
206-
FormatContainer::ForEachCallback GetFormatExactCallback() const {
207-
return m_format_exact;
208-
}
209-
FormatContainer::ForEachCallback GetFormatRegexCallback() const {
210-
return m_format_regex;
211-
}
212-
213-
SummaryContainer::ForEachCallback GetSummaryExactCallback() const {
214-
return m_summary_exact;
215-
}
216-
SummaryContainer::ForEachCallback GetSummaryRegexCallback() const {
217-
return m_summary_regex;
218-
}
219-
220-
FilterContainer::ForEachCallback GetFilterExactCallback() const {
221-
return m_filter_exact;
222-
}
223-
FilterContainer::ForEachCallback GetFilterRegexCallback() const {
224-
return m_filter_regex;
225-
}
226-
227-
SynthContainer::ForEachCallback GetSynthExactCallback() const {
228-
return m_synth_exact;
229-
}
230-
SynthContainer::ForEachCallback GetSynthRegexCallback() const {
231-
return m_synth_regex;
232-
}
233-
234-
private:
235-
FormatContainer::ForEachCallback m_format_exact;
236-
FormatContainer::ForEachCallback m_format_regex;
237-
238-
SummaryContainer::ForEachCallback m_summary_exact;
239-
SummaryContainer::ForEachCallback m_summary_regex;
240-
241-
FilterContainer::ForEachCallback m_filter_exact;
242-
FilterContainer::ForEachCallback m_filter_regex;
243-
244-
SynthContainer::ForEachCallback m_synth_exact;
245-
SynthContainer::ForEachCallback m_synth_regex;
159+
// TypeFilterImpl inherits from SyntheticChildren, so we can't simply overload
160+
// ForEach on the type of the callback because it would result in "call to
161+
// member function 'ForEach' is ambiguous" errors. Instead we use this
162+
// templated struct to hold the formatter type and the callback.
163+
template<typename T>
164+
struct ForEachCallback {
165+
// Make it constructible from any callable that fits. This allows us to use
166+
// lambdas a bit more easily at the call site. For example:
167+
// ForEachCallback<TypeFormatImpl> callback = [](...) {...};
168+
template <typename Callable> ForEachCallback(Callable c) : callback(c) {}
169+
std::function<bool(const TypeMatcher &, const std::shared_ptr<T> &)>
170+
callback;
246171
};
247172

248173
TypeCategoryImpl(IFormatChangeListener *clist, ConstString name);
249174

250-
template <typename T> void ForEach(const ForEachCallbacks<T> &foreach) {
251-
GetTypeFormatsContainer()->ForEach(foreach.GetFormatExactCallback());
252-
GetRegexTypeFormatsContainer()->ForEach(foreach.GetFormatRegexCallback());
175+
void ForEach(ForEachCallback<TypeFormatImpl> callback) {
176+
m_format_cont.ForEach(callback.callback);
177+
}
253178

254-
GetTypeSummariesContainer()->ForEach(foreach.GetSummaryExactCallback());
255-
GetRegexTypeSummariesContainer()->ForEach(
256-
foreach.GetSummaryRegexCallback());
179+
void ForEach(ForEachCallback<TypeSummaryImpl> callback) {
180+
m_summary_cont.ForEach(callback.callback);
181+
}
257182

258-
GetTypeFiltersContainer()->ForEach(foreach.GetFilterExactCallback());
259-
GetRegexTypeFiltersContainer()->ForEach(foreach.GetFilterRegexCallback());
183+
void ForEach(ForEachCallback<TypeFilterImpl> callback) {
184+
m_filter_cont.ForEach(callback.callback);
185+
}
260186

261-
GetTypeSyntheticsContainer()->ForEach(foreach.GetSynthExactCallback());
262-
GetRegexTypeSyntheticsContainer()->ForEach(foreach.GetSynthRegexCallback());
187+
void ForEach(ForEachCallback<SyntheticChildren> callback) {
188+
m_synth_cont.ForEach(callback.callback);
263189
}
264190

265191
FormatContainer::SubcontainerSP GetTypeFormatsContainer() {

lldb/source/Commands/CommandObjectType.cpp

Lines changed: 14 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1097,36 +1097,20 @@ class CommandObjectTypeFormatterList : public CommandObjectParsed {
10971097
"-----------------------\nCategory: %s%s\n-----------------------\n",
10981098
category->GetName(), category->IsEnabled() ? "" : " (disabled)");
10991099

1100-
TypeCategoryImpl::ForEachCallbacks<FormatterType> foreach;
1101-
foreach
1102-
.SetExact([&result, &formatter_regex, &any_printed](
1103-
const TypeMatcher &type_matcher,
1104-
const FormatterSharedPointer &format_sp) -> bool {
1105-
if (ShouldListItem(type_matcher.GetMatchString().GetStringRef(),
1106-
formatter_regex.get())) {
1107-
any_printed = true;
1108-
result.GetOutputStream().Printf(
1109-
"%s: %s\n", type_matcher.GetMatchString().GetCString(),
1110-
format_sp->GetDescription().c_str());
1111-
}
1112-
return true;
1113-
});
1114-
1115-
foreach
1116-
.SetWithRegex([&result, &formatter_regex, &any_printed](
1117-
const TypeMatcher &type_matcher,
1118-
const FormatterSharedPointer &format_sp) -> bool {
1119-
if (ShouldListItem(type_matcher.GetMatchString().GetStringRef(),
1120-
formatter_regex.get())) {
1121-
any_printed = true;
1122-
result.GetOutputStream().Printf(
1123-
"%s: %s\n", type_matcher.GetMatchString().GetCString(),
1124-
format_sp->GetDescription().c_str());
1125-
}
1126-
return true;
1127-
});
1128-
1129-
category->ForEach(foreach);
1100+
TypeCategoryImpl::ForEachCallback<FormatterType> print_formatter =
1101+
[&result, &formatter_regex,
1102+
&any_printed](const TypeMatcher &type_matcher,
1103+
const FormatterSharedPointer &format_sp) -> bool {
1104+
if (ShouldListItem(type_matcher.GetMatchString().GetStringRef(),
1105+
formatter_regex.get())) {
1106+
any_printed = true;
1107+
result.GetOutputStream().Printf(
1108+
"%s: %s\n", type_matcher.GetMatchString().GetCString(),
1109+
format_sp->GetDescription().c_str());
1110+
}
1111+
return true;
1112+
};
1113+
category->ForEach(print_formatter);
11301114
};
11311115

11321116
if (m_options.m_category_language.OptionWasSet()) {

0 commit comments

Comments
 (0)