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_TypeCategory_h_
10 #define lldb_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<ConstString, FormatterImpl> ExactMatchContainer;
29   typedef FormattersContainer<lldb::RegularExpressionSP, FormatterImpl>
30       RegexMatchContainer;
31 
32   typedef typename ExactMatchContainer::MapType ExactMatchMap;
33   typedef typename RegexMatchContainer::MapType RegexMatchMap;
34 
35   typedef typename ExactMatchContainer::MapValueType MapValueType;
36 
37   typedef typename ExactMatchContainer::SharedPointer ExactMatchContainerSP;
38   typedef typename RegexMatchContainer::SharedPointer RegexMatchContainerSP;
39 
40   typedef
41       typename ExactMatchContainer::ForEachCallback ExactMatchForEachCallback;
42   typedef
43       typename RegexMatchContainer::ForEachCallback RegexMatchForEachCallback;
44 
45   FormatterContainerPair(const char *exact_name, const char *regex_name,
46                          IFormatChangeListener *clist)
47       : m_exact_sp(new ExactMatchContainer(std::string(exact_name), clist)),
48         m_regex_sp(new RegexMatchContainer(std::string(regex_name), clist)) {}
49 
50   ~FormatterContainerPair() = default;
51 
52   ExactMatchContainerSP GetExactMatch() const { return m_exact_sp; }
53 
54   RegexMatchContainerSP GetRegexMatch() const { return m_regex_sp; }
55 
56   uint32_t GetCount() {
57     return GetExactMatch()->GetCount() + GetRegexMatch()->GetCount();
58   }
59 
60 private:
61   ExactMatchContainerSP m_exact_sp;
62   RegexMatchContainerSP m_regex_sp;
63 };
64 
65 class TypeCategoryImpl {
66 private:
67   typedef FormatterContainerPair<TypeFormatImpl> FormatContainer;
68   typedef FormatterContainerPair<TypeSummaryImpl> SummaryContainer;
69   typedef FormatterContainerPair<TypeFilterImpl> FilterContainer;
70   typedef FormatterContainerPair<TypeValidatorImpl> ValidatorContainer;
71   typedef FormatterContainerPair<SyntheticChildren> SynthContainer;
72 
73 public:
74   typedef uint16_t FormatCategoryItems;
75   static const uint16_t ALL_ITEM_TYPES = UINT16_MAX;
76 
77   typedef FormatContainer::ExactMatchContainerSP FormatContainerSP;
78   typedef FormatContainer::RegexMatchContainerSP RegexFormatContainerSP;
79 
80   typedef SummaryContainer::ExactMatchContainerSP SummaryContainerSP;
81   typedef SummaryContainer::RegexMatchContainerSP RegexSummaryContainerSP;
82 
83   typedef FilterContainer::ExactMatchContainerSP FilterContainerSP;
84   typedef FilterContainer::RegexMatchContainerSP RegexFilterContainerSP;
85 
86   typedef SynthContainer::ExactMatchContainerSP SynthContainerSP;
87   typedef SynthContainer::RegexMatchContainerSP RegexSynthContainerSP;
88 
89   typedef ValidatorContainer::ExactMatchContainerSP ValidatorContainerSP;
90   typedef ValidatorContainer::RegexMatchContainerSP RegexValidatorContainerSP;
91 
92   template <typename T> class ForEachCallbacks {
93   public:
94     ForEachCallbacks() = default;
95     ~ForEachCallbacks() = default;
96 
97     template <typename U = TypeFormatImpl>
98     typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type
99     SetExact(FormatContainer::ExactMatchForEachCallback callback) {
100       m_format_exact = callback;
101       return *this;
102     }
103     template <typename U = TypeFormatImpl>
104     typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type
105     SetWithRegex(FormatContainer::RegexMatchForEachCallback callback) {
106       m_format_regex = callback;
107       return *this;
108     }
109 
110     template <typename U = TypeSummaryImpl>
111     typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type
112     SetExact(SummaryContainer::ExactMatchForEachCallback callback) {
113       m_summary_exact = callback;
114       return *this;
115     }
116     template <typename U = TypeSummaryImpl>
117     typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type
118     SetWithRegex(SummaryContainer::RegexMatchForEachCallback callback) {
119       m_summary_regex = callback;
120       return *this;
121     }
122 
123     template <typename U = TypeFilterImpl>
124     typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type
125     SetExact(FilterContainer::ExactMatchForEachCallback callback) {
126       m_filter_exact = callback;
127       return *this;
128     }
129     template <typename U = TypeFilterImpl>
130     typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type
131     SetWithRegex(FilterContainer::RegexMatchForEachCallback callback) {
132       m_filter_regex = callback;
133       return *this;
134     }
135 
136     template <typename U = SyntheticChildren>
137     typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type
138     SetExact(SynthContainer::ExactMatchForEachCallback callback) {
139       m_synth_exact = callback;
140       return *this;
141     }
142     template <typename U = SyntheticChildren>
143     typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type
144     SetWithRegex(SynthContainer::RegexMatchForEachCallback callback) {
145       m_synth_regex = callback;
146       return *this;
147     }
148     template <typename U = TypeValidatorImpl>
149     typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type
150     SetExact(ValidatorContainer::ExactMatchForEachCallback callback) {
151       m_validator_exact = callback;
152       return *this;
153     }
154     template <typename U = TypeValidatorImpl>
155     typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type
156     SetWithRegex(ValidatorContainer::RegexMatchForEachCallback callback) {
157       m_validator_regex = callback;
158       return *this;
159     }
160 
161     FormatContainer::ExactMatchForEachCallback GetFormatExactCallback() const {
162       return m_format_exact;
163     }
164     FormatContainer::RegexMatchForEachCallback GetFormatRegexCallback() const {
165       return m_format_regex;
166     }
167 
168     SummaryContainer::ExactMatchForEachCallback
169     GetSummaryExactCallback() const {
170       return m_summary_exact;
171     }
172     SummaryContainer::RegexMatchForEachCallback
173     GetSummaryRegexCallback() const {
174       return m_summary_regex;
175     }
176 
177     FilterContainer::ExactMatchForEachCallback GetFilterExactCallback() const {
178       return m_filter_exact;
179     }
180     FilterContainer::RegexMatchForEachCallback GetFilterRegexCallback() const {
181       return m_filter_regex;
182     }
183 
184     SynthContainer::ExactMatchForEachCallback GetSynthExactCallback() const {
185       return m_synth_exact;
186     }
187     SynthContainer::RegexMatchForEachCallback GetSynthRegexCallback() const {
188       return m_synth_regex;
189     }
190 
191     ValidatorContainer::ExactMatchForEachCallback
192     GetValidatorExactCallback() const {
193       return m_validator_exact;
194     }
195     ValidatorContainer::RegexMatchForEachCallback
196     GetValidatorRegexCallback() const {
197       return m_validator_regex;
198     }
199 
200   private:
201     FormatContainer::ExactMatchForEachCallback m_format_exact;
202     FormatContainer::RegexMatchForEachCallback m_format_regex;
203 
204     SummaryContainer::ExactMatchForEachCallback m_summary_exact;
205     SummaryContainer::RegexMatchForEachCallback m_summary_regex;
206 
207     FilterContainer::ExactMatchForEachCallback m_filter_exact;
208     FilterContainer::RegexMatchForEachCallback m_filter_regex;
209 
210     SynthContainer::ExactMatchForEachCallback m_synth_exact;
211     SynthContainer::RegexMatchForEachCallback m_synth_regex;
212 
213     ValidatorContainer::ExactMatchForEachCallback m_validator_exact;
214     ValidatorContainer::RegexMatchForEachCallback m_validator_regex;
215   };
216 
217   TypeCategoryImpl(IFormatChangeListener *clist, ConstString name,
218                    std::initializer_list<lldb::LanguageType> langs = {});
219 
220   template <typename T> void ForEach(const ForEachCallbacks<T> &foreach) {
221     GetTypeFormatsContainer()->ForEach(foreach.GetFormatExactCallback());
222     GetRegexTypeFormatsContainer()->ForEach(foreach.GetFormatRegexCallback());
223 
224     GetTypeSummariesContainer()->ForEach(foreach.GetSummaryExactCallback());
225     GetRegexTypeSummariesContainer()->ForEach(
226         foreach.GetSummaryRegexCallback());
227 
228     GetTypeFiltersContainer()->ForEach(foreach.GetFilterExactCallback());
229     GetRegexTypeFiltersContainer()->ForEach(foreach.GetFilterRegexCallback());
230 
231     GetTypeSyntheticsContainer()->ForEach(foreach.GetSynthExactCallback());
232     GetRegexTypeSyntheticsContainer()->ForEach(foreach.GetSynthRegexCallback());
233 
234     GetTypeValidatorsContainer()->ForEach(foreach.GetValidatorExactCallback());
235     GetRegexTypeValidatorsContainer()->ForEach(
236         foreach.GetValidatorRegexCallback());
237   }
238 
239   FormatContainerSP GetTypeFormatsContainer() {
240     return m_format_cont.GetExactMatch();
241   }
242 
243   RegexFormatContainerSP GetRegexTypeFormatsContainer() {
244     return m_format_cont.GetRegexMatch();
245   }
246 
247   FormatContainer &GetFormatContainer() { return m_format_cont; }
248 
249   SummaryContainerSP GetTypeSummariesContainer() {
250     return m_summary_cont.GetExactMatch();
251   }
252 
253   RegexSummaryContainerSP GetRegexTypeSummariesContainer() {
254     return m_summary_cont.GetRegexMatch();
255   }
256 
257   SummaryContainer &GetSummaryContainer() { return m_summary_cont; }
258 
259   FilterContainerSP GetTypeFiltersContainer() {
260     return m_filter_cont.GetExactMatch();
261   }
262 
263   RegexFilterContainerSP GetRegexTypeFiltersContainer() {
264     return m_filter_cont.GetRegexMatch();
265   }
266 
267   FilterContainer &GetFilterContainer() { return m_filter_cont; }
268 
269   FormatContainer::MapValueType
270   GetFormatForType(lldb::TypeNameSpecifierImplSP type_sp);
271 
272   SummaryContainer::MapValueType
273   GetSummaryForType(lldb::TypeNameSpecifierImplSP type_sp);
274 
275   FilterContainer::MapValueType
276   GetFilterForType(lldb::TypeNameSpecifierImplSP type_sp);
277 
278   SynthContainer::MapValueType
279   GetSyntheticForType(lldb::TypeNameSpecifierImplSP type_sp);
280 
281   ValidatorContainer::MapValueType
282   GetValidatorForType(lldb::TypeNameSpecifierImplSP type_sp);
283 
284   lldb::TypeNameSpecifierImplSP
285   GetTypeNameSpecifierForFormatAtIndex(size_t index);
286 
287   lldb::TypeNameSpecifierImplSP
288   GetTypeNameSpecifierForSummaryAtIndex(size_t index);
289 
290   FormatContainer::MapValueType GetFormatAtIndex(size_t index);
291 
292   SummaryContainer::MapValueType GetSummaryAtIndex(size_t index);
293 
294   FilterContainer::MapValueType GetFilterAtIndex(size_t index);
295 
296   lldb::TypeNameSpecifierImplSP
297   GetTypeNameSpecifierForFilterAtIndex(size_t index);
298 
299   SynthContainerSP GetTypeSyntheticsContainer() {
300     return m_synth_cont.GetExactMatch();
301   }
302 
303   RegexSynthContainerSP GetRegexTypeSyntheticsContainer() {
304     return m_synth_cont.GetRegexMatch();
305   }
306 
307   SynthContainer &GetSyntheticsContainer() { return m_synth_cont; }
308 
309   SynthContainer::MapValueType GetSyntheticAtIndex(size_t index);
310 
311   lldb::TypeNameSpecifierImplSP
312   GetTypeNameSpecifierForSyntheticAtIndex(size_t index);
313 
314   ValidatorContainerSP GetTypeValidatorsContainer() {
315     return m_validator_cont.GetExactMatch();
316   }
317 
318   RegexValidatorContainerSP GetRegexTypeValidatorsContainer() {
319     return m_validator_cont.GetRegexMatch();
320   }
321 
322   ValidatorContainer::MapValueType GetValidatorAtIndex(size_t index);
323 
324   lldb::TypeNameSpecifierImplSP
325   GetTypeNameSpecifierForValidatorAtIndex(size_t index);
326 
327   bool IsEnabled() const { return m_enabled; }
328 
329   uint32_t GetEnabledPosition() {
330     if (!m_enabled)
331       return UINT32_MAX;
332     else
333       return m_enabled_position;
334   }
335 
336   bool Get(ValueObject &valobj, const FormattersMatchVector &candidates,
337            lldb::TypeFormatImplSP &entry, uint32_t *reason = nullptr);
338 
339   bool Get(ValueObject &valobj, const FormattersMatchVector &candidates,
340            lldb::TypeSummaryImplSP &entry, uint32_t *reason = nullptr);
341 
342   bool Get(ValueObject &valobj, const FormattersMatchVector &candidates,
343            lldb::SyntheticChildrenSP &entry, uint32_t *reason = nullptr);
344 
345   bool Get(ValueObject &valobj, const FormattersMatchVector &candidates,
346            lldb::TypeValidatorImplSP &entry, uint32_t *reason = nullptr);
347 
348   void Clear(FormatCategoryItems items = ALL_ITEM_TYPES);
349 
350   bool Delete(ConstString name, FormatCategoryItems items = ALL_ITEM_TYPES);
351 
352   uint32_t GetCount(FormatCategoryItems items = ALL_ITEM_TYPES);
353 
354   const char *GetName() { return m_name.GetCString(); }
355 
356   size_t GetNumLanguages();
357 
358   lldb::LanguageType GetLanguageAtIndex(size_t idx);
359 
360   void AddLanguage(lldb::LanguageType lang);
361 
362   bool HasLanguage(lldb::LanguageType lang);
363 
364   std::string GetDescription();
365 
366   bool AnyMatches(ConstString type_name,
367                   FormatCategoryItems items = ALL_ITEM_TYPES,
368                   bool only_enabled = true,
369                   const char **matching_category = nullptr,
370                   FormatCategoryItems *matching_type = nullptr);
371 
372   typedef std::shared_ptr<TypeCategoryImpl> SharedPointer;
373 
374 private:
375   FormatContainer m_format_cont;
376   SummaryContainer m_summary_cont;
377   FilterContainer m_filter_cont;
378   SynthContainer m_synth_cont;
379   ValidatorContainer m_validator_cont;
380 
381   bool m_enabled;
382 
383   IFormatChangeListener *m_change_listener;
384 
385   std::recursive_mutex m_mutex;
386 
387   ConstString m_name;
388 
389   std::vector<lldb::LanguageType> m_languages;
390 
391   uint32_t m_enabled_position;
392 
393   void Enable(bool value, uint32_t position);
394 
395   void Disable() { Enable(false, UINT32_MAX); }
396 
397   bool IsApplicable(ValueObject &valobj);
398 
399   uint32_t GetLastEnabledPosition() { return m_enabled_position; }
400 
401   void SetEnabledPosition(uint32_t p) { m_enabled_position = p; }
402 
403   friend class FormatManager;
404   friend class LanguageCategory;
405   friend class TypeCategoryMap;
406 
407   friend class FormattersContainer<ConstString, TypeFormatImpl>;
408   friend class FormattersContainer<lldb::RegularExpressionSP, TypeFormatImpl>;
409 
410   friend class FormattersContainer<ConstString, TypeSummaryImpl>;
411   friend class FormattersContainer<lldb::RegularExpressionSP, TypeSummaryImpl>;
412 
413   friend class FormattersContainer<ConstString, TypeFilterImpl>;
414   friend class FormattersContainer<lldb::RegularExpressionSP, TypeFilterImpl>;
415 
416   friend class FormattersContainer<ConstString, ScriptedSyntheticChildren>;
417   friend class FormattersContainer<lldb::RegularExpressionSP,
418                                    ScriptedSyntheticChildren>;
419 
420   friend class FormattersContainer<ConstString, TypeValidatorImpl>;
421   friend class FormattersContainer<lldb::RegularExpressionSP,
422                                    TypeValidatorImpl>;
423 };
424 
425 } // namespace lldb_private
426 
427 #endif // lldb_TypeCategory_h_
428