1//===-- TypeCategory.h ------------------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLDB_DATAFORMATTERS_TYPECATEGORY_H
10#define LLDB_DATAFORMATTERS_TYPECATEGORY_H
11
12#include <initializer_list>
13#include <memory>
14#include <mutex>
15#include <string>
16#include <vector>
17
18#include "lldb/lldb-enumerations.h"
19#include "lldb/lldb-public.h"
20
21#include "lldb/DataFormatters/FormatClasses.h"
22#include "lldb/DataFormatters/FormattersContainer.h"
23
24namespace lldb_private {
25
26template <typename FormatterImpl> class FormatterContainerPair {
27public:
28 typedef FormattersContainer<FormatterImpl> ExactMatchContainer;
29 typedef FormattersContainer<FormatterImpl> RegexMatchContainer;
30
31 typedef TypeMatcher ExactMatchMap;
32 typedef TypeMatcher RegexMatchMap;
33
34 typedef typename ExactMatchContainer::ValueSP MapValueType;
35
36 typedef typename ExactMatchContainer::SharedPointer ExactMatchContainerSP;
37 typedef typename RegexMatchContainer::SharedPointer RegexMatchContainerSP;
38
39 typedef
40 typename ExactMatchContainer::ForEachCallback ExactMatchForEachCallback;
41 typedef
42 typename RegexMatchContainer::ForEachCallback RegexMatchForEachCallback;
43
44 FormatterContainerPair(IFormatChangeListener *clist)
45 : m_exact_sp(new ExactMatchContainer(clist)),
46 m_regex_sp(new RegexMatchContainer(clist)) {}
47
48 ~FormatterContainerPair() = default;
49
50 ExactMatchContainerSP GetExactMatch() const { return m_exact_sp; }
51
52 RegexMatchContainerSP GetRegexMatch() const { return m_regex_sp; }
53
54 uint32_t GetCount() {
55 return GetExactMatch()->GetCount() + GetRegexMatch()->GetCount();
56 }
57
58private:
59 ExactMatchContainerSP m_exact_sp;
60 RegexMatchContainerSP m_regex_sp;
61};
62
63class TypeCategoryImpl {
64private:
65 typedef FormatterContainerPair<TypeFormatImpl> FormatContainer;
66 typedef FormatterContainerPair<TypeSummaryImpl> SummaryContainer;
67 typedef FormatterContainerPair<TypeFilterImpl> FilterContainer;
68 typedef FormatterContainerPair<SyntheticChildren> SynthContainer;
69
70public:
71 typedef uint16_t FormatCategoryItems;
72 static const uint16_t ALL_ITEM_TYPES = UINT16_MAX;
73
74 typedef FormatContainer::ExactMatchContainerSP FormatContainerSP;
75 typedef FormatContainer::RegexMatchContainerSP RegexFormatContainerSP;
76
77 typedef SummaryContainer::ExactMatchContainerSP SummaryContainerSP;
78 typedef SummaryContainer::RegexMatchContainerSP RegexSummaryContainerSP;
79
80 typedef FilterContainer::ExactMatchContainerSP FilterContainerSP;
81 typedef FilterContainer::RegexMatchContainerSP RegexFilterContainerSP;
82
83 typedef SynthContainer::ExactMatchContainerSP SynthContainerSP;
84 typedef SynthContainer::RegexMatchContainerSP RegexSynthContainerSP;
85
86 template <typename T> class ForEachCallbacks {
87 public:
88 ForEachCallbacks() = default;
89 ~ForEachCallbacks() = default;
90
91 template <typename U = TypeFormatImpl>
92 typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type
93 SetExact(FormatContainer::ExactMatchForEachCallback callback) {
94 m_format_exact = std::move(callback);
95 return *this;
96 }
97 template <typename U = TypeFormatImpl>
98 typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type
99 SetWithRegex(FormatContainer::RegexMatchForEachCallback callback) {
100 m_format_regex = std::move(callback);
101 return *this;
102 }
103
104 template <typename U = TypeSummaryImpl>
105 typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type
106 SetExact(SummaryContainer::ExactMatchForEachCallback callback) {
107 m_summary_exact = std::move(callback);
108 return *this;
109 }
110 template <typename U = TypeSummaryImpl>
111 typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type
112 SetWithRegex(SummaryContainer::RegexMatchForEachCallback callback) {
113 m_summary_regex = std::move(callback);
114 return *this;
115 }
116
117 template <typename U = TypeFilterImpl>
118 typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type
119 SetExact(FilterContainer::ExactMatchForEachCallback callback) {
120 m_filter_exact = std::move(callback);
121 return *this;
122 }
123 template <typename U = TypeFilterImpl>
124 typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type
125 SetWithRegex(FilterContainer::RegexMatchForEachCallback callback) {
126 m_filter_regex = std::move(callback);
127 return *this;
128 }
129
130 template <typename U = SyntheticChildren>
131 typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type
132 SetExact(SynthContainer::ExactMatchForEachCallback callback) {
133 m_synth_exact = std::move(callback);
134 return *this;
135 }
136 template <typename U = SyntheticChildren>
137 typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type
138 SetWithRegex(SynthContainer::RegexMatchForEachCallback callback) {
139 m_synth_regex = std::move(callback);
140 return *this;
141 }
142
143 FormatContainer::ExactMatchForEachCallback GetFormatExactCallback() const {
144 return m_format_exact;
145 }
146 FormatContainer::RegexMatchForEachCallback GetFormatRegexCallback() const {
147 return m_format_regex;
148 }
149
150 SummaryContainer::ExactMatchForEachCallback
151 GetSummaryExactCallback() const {
152 return m_summary_exact;
153 }
154 SummaryContainer::RegexMatchForEachCallback
155 GetSummaryRegexCallback() const {
156 return m_summary_regex;
157 }
158
159 FilterContainer::ExactMatchForEachCallback GetFilterExactCallback() const {
160 return m_filter_exact;
161 }
162 FilterContainer::RegexMatchForEachCallback GetFilterRegexCallback() const {
163 return m_filter_regex;
164 }
165
166 SynthContainer::ExactMatchForEachCallback GetSynthExactCallback() const {
167 return m_synth_exact;
168 }
169 SynthContainer::RegexMatchForEachCallback GetSynthRegexCallback() const {
170 return m_synth_regex;
171 }
172
173 private:
174 FormatContainer::ExactMatchForEachCallback m_format_exact;
175 FormatContainer::RegexMatchForEachCallback m_format_regex;
176
177 SummaryContainer::ExactMatchForEachCallback m_summary_exact;
178 SummaryContainer::RegexMatchForEachCallback m_summary_regex;
179
180 FilterContainer::ExactMatchForEachCallback m_filter_exact;
181 FilterContainer::RegexMatchForEachCallback m_filter_regex;
182
183 SynthContainer::ExactMatchForEachCallback m_synth_exact;
184 SynthContainer::RegexMatchForEachCallback m_synth_regex;
185 };
186
187 TypeCategoryImpl(IFormatChangeListener *clist, ConstString name);
188
189 template <typename T> void ForEach(const ForEachCallbacks<T> &foreach) {
190 GetTypeFormatsContainer()->ForEach(foreach.GetFormatExactCallback());
191 GetRegexTypeFormatsContainer()->ForEach(foreach.GetFormatRegexCallback());
192
193 GetTypeSummariesContainer()->ForEach(foreach.GetSummaryExactCallback());
194 GetRegexTypeSummariesContainer()->ForEach(
195 foreach.GetSummaryRegexCallback());
196
197 GetTypeFiltersContainer()->ForEach(foreach.GetFilterExactCallback());
198 GetRegexTypeFiltersContainer()->ForEach(foreach.GetFilterRegexCallback());
199
200 GetTypeSyntheticsContainer()->ForEach(foreach.GetSynthExactCallback());
201 GetRegexTypeSyntheticsContainer()->ForEach(foreach.GetSynthRegexCallback());
202 }
203
204 FormatContainerSP GetTypeFormatsContainer() {
205 return m_format_cont.GetExactMatch();
206 }
207
208 RegexFormatContainerSP GetRegexTypeFormatsContainer() {
209 return m_format_cont.GetRegexMatch();
210 }
211
212 FormatContainer &GetFormatContainer() { return m_format_cont; }
213
214 SummaryContainerSP GetTypeSummariesContainer() {
215 return m_summary_cont.GetExactMatch();
216 }
217
218 RegexSummaryContainerSP GetRegexTypeSummariesContainer() {
219 return m_summary_cont.GetRegexMatch();
220 }
221
222 SummaryContainer &GetSummaryContainer() { return m_summary_cont; }
223
224 FilterContainerSP GetTypeFiltersContainer() {
225 return m_filter_cont.GetExactMatch();
226 }
227
228 RegexFilterContainerSP GetRegexTypeFiltersContainer() {
229 return m_filter_cont.GetRegexMatch();
230 }
231
232 FilterContainer &GetFilterContainer() { return m_filter_cont; }
233
234 FormatContainer::MapValueType
235 GetFormatForType(lldb::TypeNameSpecifierImplSP type_sp);
236
237 SummaryContainer::MapValueType
238 GetSummaryForType(lldb::TypeNameSpecifierImplSP type_sp);
239
240 FilterContainer::MapValueType
241 GetFilterForType(lldb::TypeNameSpecifierImplSP type_sp);
242
243 SynthContainer::MapValueType
244 GetSyntheticForType(lldb::TypeNameSpecifierImplSP type_sp);
245
246 lldb::TypeNameSpecifierImplSP
247 GetTypeNameSpecifierForFormatAtIndex(size_t index);
248
249 lldb::TypeNameSpecifierImplSP
250 GetTypeNameSpecifierForSummaryAtIndex(size_t index);
251
252 FormatContainer::MapValueType GetFormatAtIndex(size_t index);
253
254 SummaryContainer::MapValueType GetSummaryAtIndex(size_t index);
255
256 FilterContainer::MapValueType GetFilterAtIndex(size_t index);
257
258 lldb::TypeNameSpecifierImplSP
259 GetTypeNameSpecifierForFilterAtIndex(size_t index);
260
261 SynthContainerSP GetTypeSyntheticsContainer() {
262 return m_synth_cont.GetExactMatch();
263 }
264
265 RegexSynthContainerSP GetRegexTypeSyntheticsContainer() {
266 return m_synth_cont.GetRegexMatch();
267 }
268
269 SynthContainer &GetSyntheticsContainer() { return m_synth_cont; }
270
271 SynthContainer::MapValueType GetSyntheticAtIndex(size_t index);
272
273 lldb::TypeNameSpecifierImplSP
274 GetTypeNameSpecifierForSyntheticAtIndex(size_t index);
275
276 bool IsEnabled() const { return m_enabled; }
277
278 uint32_t GetEnabledPosition() {
279 if (!m_enabled)
280 return UINT32_MAX;
281 else
282 return m_enabled_position;
283 }
284
285 bool Get(lldb::LanguageType lang, const FormattersMatchVector &candidates,
286 lldb::TypeFormatImplSP &entry);
287
288 bool Get(lldb::LanguageType lang, const FormattersMatchVector &candidates,
289 lldb::TypeSummaryImplSP &entry);
290
291 bool Get(lldb::LanguageType lang, const FormattersMatchVector &candidates,
292 lldb::SyntheticChildrenSP &entry);
293
294 void Clear(FormatCategoryItems items = ALL_ITEM_TYPES);
295
296 bool Delete(ConstString name, FormatCategoryItems items = ALL_ITEM_TYPES);
297
298 uint32_t GetCount(FormatCategoryItems items = ALL_ITEM_TYPES);
299
300 const char *GetName() { return m_name.GetCString(); }
301
302 size_t GetNumLanguages();
303
304 lldb::LanguageType GetLanguageAtIndex(size_t idx);
305
306 void AddLanguage(lldb::LanguageType lang);
307
308 std::string GetDescription();
309
310 bool AnyMatches(ConstString type_name,
311 FormatCategoryItems items = ALL_ITEM_TYPES,
312 bool only_enabled = true,
313 const char **matching_category = nullptr,
314 FormatCategoryItems *matching_type = nullptr);
315
316 typedef std::shared_ptr<TypeCategoryImpl> SharedPointer;
317
318private:
319 FormatContainer m_format_cont;
320 SummaryContainer m_summary_cont;
321 FilterContainer m_filter_cont;
322 SynthContainer m_synth_cont;
323
324 bool m_enabled;
325
326 IFormatChangeListener *m_change_listener;
327
328 std::recursive_mutex m_mutex;
329
330 ConstString m_name;
331
332 std::vector<lldb::LanguageType> m_languages;
333
334 uint32_t m_enabled_position;
335
336 void Enable(bool value, uint32_t position);
337
338 void Disable() { Enable(false, UINT32_MAX); }
339
340 bool IsApplicable(lldb::LanguageType lang);
341
342 uint32_t GetLastEnabledPosition() { return m_enabled_position; }
343
344 void SetEnabledPosition(uint32_t p) { m_enabled_position = p; }
345
346 friend class FormatManager;
347 friend class LanguageCategory;
348 friend class TypeCategoryMap;
349
350 friend class FormattersContainer<TypeFormatImpl>;
351
352 friend class FormattersContainer<TypeSummaryImpl>;
353
354 friend class FormattersContainer<TypeFilterImpl>;
355
356 friend class FormattersContainer<ScriptedSyntheticChildren>;
357};
358
359} // namespace lldb_private
360
361#endif // LLDB_DATAFORMATTERS_TYPECATEGORY_H
362