1296417Sdim//===-- TypeCategory.h ------------------------------------------*- C++ -*-===//
2254721Semaste//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6254721Semaste//
7254721Semaste//===----------------------------------------------------------------------===//
8254721Semaste
9254721Semaste#ifndef lldb_TypeCategory_h_
10254721Semaste#define lldb_TypeCategory_h_
11254721Semaste
12296417Sdim#include <initializer_list>
13296417Sdim#include <memory>
14309124Sdim#include <mutex>
15296417Sdim#include <string>
16296417Sdim#include <vector>
17254721Semaste
18314564Sdim#include "lldb/lldb-enumerations.h"
19254721Semaste#include "lldb/lldb-public.h"
20254721Semaste
21258884Semaste#include "lldb/DataFormatters/FormatClasses.h"
22262528Semaste#include "lldb/DataFormatters/FormattersContainer.h"
23254721Semaste
24262528Semastenamespace lldb_private {
25262528Semaste
26314564Sdimtemplate <typename FormatterImpl> class FormatterContainerPair {
27314564Sdimpublic:
28314564Sdim  typedef FormattersContainer<ConstString, FormatterImpl> ExactMatchContainer;
29360784Sdim  typedef FormattersContainer<RegularExpression, FormatterImpl>
30314564Sdim      RegexMatchContainer;
31258054Semaste
32314564Sdim  typedef typename ExactMatchContainer::MapType ExactMatchMap;
33314564Sdim  typedef typename RegexMatchContainer::MapType RegexMatchMap;
34314564Sdim
35314564Sdim  typedef typename ExactMatchContainer::MapValueType MapValueType;
36314564Sdim
37314564Sdim  typedef typename ExactMatchContainer::SharedPointer ExactMatchContainerSP;
38314564Sdim  typedef typename RegexMatchContainer::SharedPointer RegexMatchContainerSP;
39314564Sdim
40314564Sdim  typedef
41314564Sdim      typename ExactMatchContainer::ForEachCallback ExactMatchForEachCallback;
42314564Sdim  typedef
43314564Sdim      typename RegexMatchContainer::ForEachCallback RegexMatchForEachCallback;
44314564Sdim
45314564Sdim  FormatterContainerPair(const char *exact_name, const char *regex_name,
46314564Sdim                         IFormatChangeListener *clist)
47314564Sdim      : m_exact_sp(new ExactMatchContainer(std::string(exact_name), clist)),
48314564Sdim        m_regex_sp(new RegexMatchContainer(std::string(regex_name), clist)) {}
49314564Sdim
50314564Sdim  ~FormatterContainerPair() = default;
51314564Sdim
52314564Sdim  ExactMatchContainerSP GetExactMatch() const { return m_exact_sp; }
53314564Sdim
54314564Sdim  RegexMatchContainerSP GetRegexMatch() const { return m_regex_sp; }
55314564Sdim
56314564Sdim  uint32_t GetCount() {
57314564Sdim    return GetExactMatch()->GetCount() + GetRegexMatch()->GetCount();
58314564Sdim  }
59314564Sdim
60314564Sdimprivate:
61314564Sdim  ExactMatchContainerSP m_exact_sp;
62314564Sdim  RegexMatchContainerSP m_regex_sp;
63314564Sdim};
64314564Sdim
65314564Sdimclass TypeCategoryImpl {
66314564Sdimprivate:
67314564Sdim  typedef FormatterContainerPair<TypeFormatImpl> FormatContainer;
68314564Sdim  typedef FormatterContainerPair<TypeSummaryImpl> SummaryContainer;
69314564Sdim  typedef FormatterContainerPair<TypeFilterImpl> FilterContainer;
70314564Sdim  typedef FormatterContainerPair<SyntheticChildren> SynthContainer;
71262528Semaste
72314564Sdimpublic:
73314564Sdim  typedef uint16_t FormatCategoryItems;
74314564Sdim  static const uint16_t ALL_ITEM_TYPES = UINT16_MAX;
75258054Semaste
76314564Sdim  typedef FormatContainer::ExactMatchContainerSP FormatContainerSP;
77314564Sdim  typedef FormatContainer::RegexMatchContainerSP RegexFormatContainerSP;
78258054Semaste
79314564Sdim  typedef SummaryContainer::ExactMatchContainerSP SummaryContainerSP;
80314564Sdim  typedef SummaryContainer::RegexMatchContainerSP RegexSummaryContainerSP;
81314564Sdim
82314564Sdim  typedef FilterContainer::ExactMatchContainerSP FilterContainerSP;
83314564Sdim  typedef FilterContainer::RegexMatchContainerSP RegexFilterContainerSP;
84353358Sdim
85314564Sdim  typedef SynthContainer::ExactMatchContainerSP SynthContainerSP;
86314564Sdim  typedef SynthContainer::RegexMatchContainerSP RegexSynthContainerSP;
87296417Sdim
88314564Sdim  template <typename T> class ForEachCallbacks {
89314564Sdim  public:
90314564Sdim    ForEachCallbacks() = default;
91314564Sdim    ~ForEachCallbacks() = default;
92296417Sdim
93314564Sdim    template <typename U = TypeFormatImpl>
94314564Sdim    typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type
95314564Sdim    SetExact(FormatContainer::ExactMatchForEachCallback callback) {
96314564Sdim      m_format_exact = callback;
97314564Sdim      return *this;
98314564Sdim    }
99314564Sdim    template <typename U = TypeFormatImpl>
100314564Sdim    typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type
101314564Sdim    SetWithRegex(FormatContainer::RegexMatchForEachCallback callback) {
102314564Sdim      m_format_regex = callback;
103314564Sdim      return *this;
104314564Sdim    }
105314564Sdim
106314564Sdim    template <typename U = TypeSummaryImpl>
107314564Sdim    typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type
108314564Sdim    SetExact(SummaryContainer::ExactMatchForEachCallback callback) {
109314564Sdim      m_summary_exact = callback;
110314564Sdim      return *this;
111314564Sdim    }
112314564Sdim    template <typename U = TypeSummaryImpl>
113314564Sdim    typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type
114314564Sdim    SetWithRegex(SummaryContainer::RegexMatchForEachCallback callback) {
115314564Sdim      m_summary_regex = callback;
116314564Sdim      return *this;
117314564Sdim    }
118314564Sdim
119314564Sdim    template <typename U = TypeFilterImpl>
120314564Sdim    typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type
121314564Sdim    SetExact(FilterContainer::ExactMatchForEachCallback callback) {
122314564Sdim      m_filter_exact = callback;
123314564Sdim      return *this;
124314564Sdim    }
125314564Sdim    template <typename U = TypeFilterImpl>
126314564Sdim    typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type
127314564Sdim    SetWithRegex(FilterContainer::RegexMatchForEachCallback callback) {
128314564Sdim      m_filter_regex = callback;
129314564Sdim      return *this;
130314564Sdim    }
131314564Sdim
132314564Sdim    template <typename U = SyntheticChildren>
133314564Sdim    typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type
134314564Sdim    SetExact(SynthContainer::ExactMatchForEachCallback callback) {
135314564Sdim      m_synth_exact = callback;
136314564Sdim      return *this;
137314564Sdim    }
138314564Sdim    template <typename U = SyntheticChildren>
139314564Sdim    typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type
140314564Sdim    SetWithRegex(SynthContainer::RegexMatchForEachCallback callback) {
141314564Sdim      m_synth_regex = callback;
142314564Sdim      return *this;
143314564Sdim    }
144296417Sdim
145314564Sdim    FormatContainer::ExactMatchForEachCallback GetFormatExactCallback() const {
146314564Sdim      return m_format_exact;
147314564Sdim    }
148314564Sdim    FormatContainer::RegexMatchForEachCallback GetFormatRegexCallback() const {
149314564Sdim      return m_format_regex;
150314564Sdim    }
151296417Sdim
152314564Sdim    SummaryContainer::ExactMatchForEachCallback
153314564Sdim    GetSummaryExactCallback() const {
154314564Sdim      return m_summary_exact;
155314564Sdim    }
156314564Sdim    SummaryContainer::RegexMatchForEachCallback
157314564Sdim    GetSummaryRegexCallback() const {
158314564Sdim      return m_summary_regex;
159314564Sdim    }
160296417Sdim
161314564Sdim    FilterContainer::ExactMatchForEachCallback GetFilterExactCallback() const {
162314564Sdim      return m_filter_exact;
163314564Sdim    }
164314564Sdim    FilterContainer::RegexMatchForEachCallback GetFilterRegexCallback() const {
165314564Sdim      return m_filter_regex;
166314564Sdim    }
167314564Sdim
168314564Sdim    SynthContainer::ExactMatchForEachCallback GetSynthExactCallback() const {
169314564Sdim      return m_synth_exact;
170314564Sdim    }
171314564Sdim    SynthContainer::RegexMatchForEachCallback GetSynthRegexCallback() const {
172314564Sdim      return m_synth_regex;
173314564Sdim    }
174296417Sdim
175314564Sdim  private:
176314564Sdim    FormatContainer::ExactMatchForEachCallback m_format_exact;
177314564Sdim    FormatContainer::RegexMatchForEachCallback m_format_regex;
178296417Sdim
179314564Sdim    SummaryContainer::ExactMatchForEachCallback m_summary_exact;
180314564Sdim    SummaryContainer::RegexMatchForEachCallback m_summary_regex;
181314564Sdim
182314564Sdim    FilterContainer::ExactMatchForEachCallback m_filter_exact;
183314564Sdim    FilterContainer::RegexMatchForEachCallback m_filter_regex;
184314564Sdim
185314564Sdim    SynthContainer::ExactMatchForEachCallback m_synth_exact;
186314564Sdim    SynthContainer::RegexMatchForEachCallback m_synth_regex;
187314564Sdim  };
188314564Sdim
189360784Sdim  TypeCategoryImpl(IFormatChangeListener *clist, ConstString name);
190314564Sdim
191314564Sdim  template <typename T> void ForEach(const ForEachCallbacks<T> &foreach) {
192314564Sdim    GetTypeFormatsContainer()->ForEach(foreach.GetFormatExactCallback());
193314564Sdim    GetRegexTypeFormatsContainer()->ForEach(foreach.GetFormatRegexCallback());
194314564Sdim
195314564Sdim    GetTypeSummariesContainer()->ForEach(foreach.GetSummaryExactCallback());
196314564Sdim    GetRegexTypeSummariesContainer()->ForEach(
197314564Sdim        foreach.GetSummaryRegexCallback());
198314564Sdim
199314564Sdim    GetTypeFiltersContainer()->ForEach(foreach.GetFilterExactCallback());
200314564Sdim    GetRegexTypeFiltersContainer()->ForEach(foreach.GetFilterRegexCallback());
201314564Sdim
202314564Sdim    GetTypeSyntheticsContainer()->ForEach(foreach.GetSynthExactCallback());
203314564Sdim    GetRegexTypeSyntheticsContainer()->ForEach(foreach.GetSynthRegexCallback());
204314564Sdim  }
205314564Sdim
206314564Sdim  FormatContainerSP GetTypeFormatsContainer() {
207314564Sdim    return m_format_cont.GetExactMatch();
208314564Sdim  }
209314564Sdim
210314564Sdim  RegexFormatContainerSP GetRegexTypeFormatsContainer() {
211314564Sdim    return m_format_cont.GetRegexMatch();
212314564Sdim  }
213314564Sdim
214314564Sdim  FormatContainer &GetFormatContainer() { return m_format_cont; }
215314564Sdim
216314564Sdim  SummaryContainerSP GetTypeSummariesContainer() {
217314564Sdim    return m_summary_cont.GetExactMatch();
218314564Sdim  }
219314564Sdim
220314564Sdim  RegexSummaryContainerSP GetRegexTypeSummariesContainer() {
221314564Sdim    return m_summary_cont.GetRegexMatch();
222314564Sdim  }
223314564Sdim
224314564Sdim  SummaryContainer &GetSummaryContainer() { return m_summary_cont; }
225314564Sdim
226314564Sdim  FilterContainerSP GetTypeFiltersContainer() {
227314564Sdim    return m_filter_cont.GetExactMatch();
228314564Sdim  }
229314564Sdim
230314564Sdim  RegexFilterContainerSP GetRegexTypeFiltersContainer() {
231314564Sdim    return m_filter_cont.GetRegexMatch();
232314564Sdim  }
233314564Sdim
234314564Sdim  FilterContainer &GetFilterContainer() { return m_filter_cont; }
235314564Sdim
236314564Sdim  FormatContainer::MapValueType
237314564Sdim  GetFormatForType(lldb::TypeNameSpecifierImplSP type_sp);
238314564Sdim
239314564Sdim  SummaryContainer::MapValueType
240314564Sdim  GetSummaryForType(lldb::TypeNameSpecifierImplSP type_sp);
241314564Sdim
242314564Sdim  FilterContainer::MapValueType
243314564Sdim  GetFilterForType(lldb::TypeNameSpecifierImplSP type_sp);
244314564Sdim
245314564Sdim  SynthContainer::MapValueType
246314564Sdim  GetSyntheticForType(lldb::TypeNameSpecifierImplSP type_sp);
247258054Semaste
248314564Sdim  lldb::TypeNameSpecifierImplSP
249314564Sdim  GetTypeNameSpecifierForFormatAtIndex(size_t index);
250314564Sdim
251314564Sdim  lldb::TypeNameSpecifierImplSP
252314564Sdim  GetTypeNameSpecifierForSummaryAtIndex(size_t index);
253314564Sdim
254314564Sdim  FormatContainer::MapValueType GetFormatAtIndex(size_t index);
255314564Sdim
256314564Sdim  SummaryContainer::MapValueType GetSummaryAtIndex(size_t index);
257314564Sdim
258314564Sdim  FilterContainer::MapValueType GetFilterAtIndex(size_t index);
259314564Sdim
260314564Sdim  lldb::TypeNameSpecifierImplSP
261314564Sdim  GetTypeNameSpecifierForFilterAtIndex(size_t index);
262314564Sdim
263314564Sdim  SynthContainerSP GetTypeSyntheticsContainer() {
264314564Sdim    return m_synth_cont.GetExactMatch();
265314564Sdim  }
266314564Sdim
267314564Sdim  RegexSynthContainerSP GetRegexTypeSyntheticsContainer() {
268314564Sdim    return m_synth_cont.GetRegexMatch();
269314564Sdim  }
270314564Sdim
271314564Sdim  SynthContainer &GetSyntheticsContainer() { return m_synth_cont; }
272314564Sdim
273314564Sdim  SynthContainer::MapValueType GetSyntheticAtIndex(size_t index);
274314564Sdim
275314564Sdim  lldb::TypeNameSpecifierImplSP
276314564Sdim  GetTypeNameSpecifierForSyntheticAtIndex(size_t index);
277296417Sdim
278314564Sdim  bool IsEnabled() const { return m_enabled; }
279314564Sdim
280314564Sdim  uint32_t GetEnabledPosition() {
281344779Sdim    if (!m_enabled)
282314564Sdim      return UINT32_MAX;
283314564Sdim    else
284314564Sdim      return m_enabled_position;
285314564Sdim  }
286314564Sdim
287360784Sdim  bool Get(lldb::LanguageType lang, const FormattersMatchVector &candidates,
288314564Sdim           lldb::TypeFormatImplSP &entry, uint32_t *reason = nullptr);
289314564Sdim
290360784Sdim  bool Get(lldb::LanguageType lang, const FormattersMatchVector &candidates,
291314564Sdim           lldb::TypeSummaryImplSP &entry, uint32_t *reason = nullptr);
292314564Sdim
293360784Sdim  bool Get(lldb::LanguageType lang, const FormattersMatchVector &candidates,
294314564Sdim           lldb::SyntheticChildrenSP &entry, uint32_t *reason = nullptr);
295314564Sdim
296314564Sdim  void Clear(FormatCategoryItems items = ALL_ITEM_TYPES);
297314564Sdim
298314564Sdim  bool Delete(ConstString name, FormatCategoryItems items = ALL_ITEM_TYPES);
299314564Sdim
300314564Sdim  uint32_t GetCount(FormatCategoryItems items = ALL_ITEM_TYPES);
301314564Sdim
302314564Sdim  const char *GetName() { return m_name.GetCString(); }
303314564Sdim
304314564Sdim  size_t GetNumLanguages();
305314564Sdim
306314564Sdim  lldb::LanguageType GetLanguageAtIndex(size_t idx);
307314564Sdim
308314564Sdim  void AddLanguage(lldb::LanguageType lang);
309314564Sdim
310314564Sdim  std::string GetDescription();
311314564Sdim
312314564Sdim  bool AnyMatches(ConstString type_name,
313314564Sdim                  FormatCategoryItems items = ALL_ITEM_TYPES,
314314564Sdim                  bool only_enabled = true,
315314564Sdim                  const char **matching_category = nullptr,
316314564Sdim                  FormatCategoryItems *matching_type = nullptr);
317314564Sdim
318314564Sdim  typedef std::shared_ptr<TypeCategoryImpl> SharedPointer;
319314564Sdim
320314564Sdimprivate:
321314564Sdim  FormatContainer m_format_cont;
322314564Sdim  SummaryContainer m_summary_cont;
323314564Sdim  FilterContainer m_filter_cont;
324314564Sdim  SynthContainer m_synth_cont;
325309124Sdim
326314564Sdim  bool m_enabled;
327309124Sdim
328314564Sdim  IFormatChangeListener *m_change_listener;
329296417Sdim
330314564Sdim  std::recursive_mutex m_mutex;
331296417Sdim
332314564Sdim  ConstString m_name;
333314564Sdim
334314564Sdim  std::vector<lldb::LanguageType> m_languages;
335314564Sdim
336314564Sdim  uint32_t m_enabled_position;
337314564Sdim
338314564Sdim  void Enable(bool value, uint32_t position);
339314564Sdim
340314564Sdim  void Disable() { Enable(false, UINT32_MAX); }
341314564Sdim
342360784Sdim  bool IsApplicable(lldb::LanguageType lang);
343314564Sdim
344314564Sdim  uint32_t GetLastEnabledPosition() { return m_enabled_position; }
345314564Sdim
346314564Sdim  void SetEnabledPosition(uint32_t p) { m_enabled_position = p; }
347314564Sdim
348314564Sdim  friend class FormatManager;
349314564Sdim  friend class LanguageCategory;
350314564Sdim  friend class TypeCategoryMap;
351314564Sdim
352314564Sdim  friend class FormattersContainer<ConstString, TypeFormatImpl>;
353314564Sdim  friend class FormattersContainer<lldb::RegularExpressionSP, TypeFormatImpl>;
354314564Sdim
355314564Sdim  friend class FormattersContainer<ConstString, TypeSummaryImpl>;
356314564Sdim  friend class FormattersContainer<lldb::RegularExpressionSP, TypeSummaryImpl>;
357314564Sdim
358314564Sdim  friend class FormattersContainer<ConstString, TypeFilterImpl>;
359314564Sdim  friend class FormattersContainer<lldb::RegularExpressionSP, TypeFilterImpl>;
360314564Sdim
361314564Sdim  friend class FormattersContainer<ConstString, ScriptedSyntheticChildren>;
362314564Sdim  friend class FormattersContainer<lldb::RegularExpressionSP,
363314564Sdim                                   ScriptedSyntheticChildren>;
364314564Sdim
365314564Sdim};
366314564Sdim
367254721Semaste} // namespace lldb_private
368254721Semaste
369296417Sdim#endif // lldb_TypeCategory_h_
370