TypeCategory.h revision 360660
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
24namespace lldb_private {
25
26template <typename FormatterImpl> class FormatterContainerPair {
27public:
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
60private:
61  ExactMatchContainerSP m_exact_sp;
62  RegexMatchContainerSP m_regex_sp;
63};
64
65class TypeCategoryImpl {
66private:
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
73public:
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
374private:
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