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 | |
24 | namespace lldb_private { |
25 | |
26 | template <typename FormatterImpl> class FormatterContainerPair { |
27 | public: |
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 | |
58 | private: |
59 | ExactMatchContainerSP m_exact_sp; |
60 | RegexMatchContainerSP m_regex_sp; |
61 | }; |
62 | |
63 | class TypeCategoryImpl { |
64 | private: |
65 | typedef FormatterContainerPair<TypeFormatImpl> FormatContainer; |
66 | typedef FormatterContainerPair<TypeSummaryImpl> SummaryContainer; |
67 | typedef FormatterContainerPair<TypeFilterImpl> FilterContainer; |
68 | typedef FormatterContainerPair<SyntheticChildren> SynthContainer; |
69 | |
70 | public: |
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 | |
318 | private: |
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 | |