LLDB mainline
TypeCategory.h
Go to the documentation of this file.
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 <array>
13#include <initializer_list>
14#include <memory>
15#include <mutex>
16#include <string>
17#include <vector>
18
20#include "lldb/lldb-public.h"
21
24
25namespace lldb_private {
26
27// A formatter container with sub-containers for different priority tiers, that
28// also exposes a flat view of all formatters in it.
29//
30// Formatters have different priority during matching, depending on the type of
31// matching specified at registration. Exact matchers are processed first, then
32// regex, and finally callback matchers. However, the scripting API presents a
33// flat view of formatters in a category, with methods like `GetNumFormats()`
34// and `GetFormatAtIndex(i)`. So we need something that can behave like both
35// representations.
36template <typename FormatterImpl> class TieredFormatterContainer {
37public:
39 using SubcontainerSP = std::shared_ptr<Subcontainer>;
42
44 for (auto& sc : m_subcontainers)
45 sc = std::make_shared<Subcontainer>(change_listener);
46 }
47
48 /// Clears all subcontainers.
49 void Clear() {
50 for (auto sc : m_subcontainers)
51 sc->Clear();
52 }
53
54 /// Adds a formatter to the right subcontainer depending on the matching type
55 /// specified by `type_sp`.
56 void Add(lldb::TypeNameSpecifierImplSP type_sp,
57 std::shared_ptr<FormatterImpl> format_sp) {
58 m_subcontainers[type_sp->GetMatchType()]->Add(TypeMatcher(type_sp),
59 format_sp);
60 }
61
62 /// Deletes the formatter specified by `type_sp`.
63 bool Delete(lldb::TypeNameSpecifierImplSP type_sp) {
64 return m_subcontainers[type_sp->GetMatchType()]->Delete(
65 TypeMatcher(type_sp));
66 }
67
68 /// Deletes all formatters registered with the string `name`, in all
69 /// subcontainers.
70 bool Delete(ConstString name) {
71 bool success = false;
72 for (auto sc : m_subcontainers)
73 success = sc->Delete(name) || success;
74 return success;
75 }
76
77 /// Returns the total count of elements across all subcontainers.
79 uint32_t result = 0;
80 for (auto sc : m_subcontainers)
81 result += sc->GetCount();
82 return result;
83 }
84
85 /// Returns the formatter at `index`, simulating a flattened view of all
86 /// subcontainers in priority order.
87 MapValueType GetAtIndex(size_t index) {
88 for (auto sc : m_subcontainers) {
89 if (index < sc->GetCount())
90 return sc->GetAtIndex(index);
91 index -= sc->GetCount();
92 }
93 return MapValueType();
94 }
95
96 /// Looks for a matching candidate across all priority tiers, in priority
97 /// order. If a match is found, returns `true` and puts the matching entry in
98 /// `entry`.
99 bool Get(const FormattersMatchVector &candidates,
100 std::shared_ptr<FormatterImpl> &entry) {
101 for (auto sc : m_subcontainers) {
102 if (sc->Get(candidates, entry))
103 return true;
104 }
105 return false;
106 }
107
108 bool AnyMatches(const FormattersMatchCandidate &candidate) {
109 std::shared_ptr<FormatterImpl> entry;
110 for (auto sc : m_subcontainers) {
111 if (sc->Get(FormattersMatchVector{candidate}, entry))
112 return true;
113 }
114 return false;
115 }
116
117 /// Returns a formatter that is an exact match for `type_specifier_sp`. It
118 /// looks for a formatter with the same matching type that was created from
119 /// the same string. This is useful so we can refer to a formatter using the
120 /// same string used to register it.
121 ///
122 /// For example, `type_specifier_sp` can be something like
123 /// {"std::vector<.*>", eFormatterMatchRegex}, and we'd look for a regex
124 /// matcher with that exact regex string, NOT try to match that string using
125 /// regex.
127 GetForTypeNameSpecifier(lldb::TypeNameSpecifierImplSP type_specifier_sp) {
128 MapValueType retval;
129 if (type_specifier_sp) {
130 m_subcontainers[type_specifier_sp->GetMatchType()]->GetExact(
131 ConstString(type_specifier_sp->GetName()), retval);
132 }
133 return retval;
134 }
135
136 /// Returns the type name specifier at `index`, simulating a flattened view of
137 /// all subcontainers in priority order.
138 lldb::TypeNameSpecifierImplSP GetTypeNameSpecifierAtIndex(size_t index) {
139 for (auto sc : m_subcontainers) {
140 if (index < sc->GetCount())
141 return sc->GetTypeNameSpecifierAtIndex(index);
142 index -= sc->GetCount();
143 }
144 return lldb::TypeNameSpecifierImplSP();
145 }
146
147 /// Iterates through tiers in order, running `callback` on each element of
148 /// each tier.
149 void ForEach(std::function<bool(const TypeMatcher &,
150 const std::shared_ptr<FormatterImpl> &)>
151 callback) {
152 for (auto sc : m_subcontainers) {
153 sc->ForEach(callback);
154 }
155 }
156
158 for (auto sc: m_subcontainers)
159 sc->AutoComplete(request);
160 }
161
162 private:
163 std::array<std::shared_ptr<Subcontainer>, lldb::eLastFormatterMatchType + 1>
165};
166
168private:
173
174public:
176 static const uint16_t ALL_ITEM_TYPES = UINT16_MAX;
177
178 // TypeFilterImpl inherits from SyntheticChildren, so we can't simply overload
179 // ForEach on the type of the callback because it would result in "call to
180 // member function 'ForEach' is ambiguous" errors. Instead we use this
181 // templated struct to hold the formatter type and the callback.
182 template<typename T>
184 // Make it constructible from any callable that fits. This allows us to use
185 // lambdas a bit more easily at the call site. For example:
186 // ForEachCallback<TypeFormatImpl> callback = [](...) {...};
187 template <typename Callable> ForEachCallback(Callable c) : callback(c) {}
188 std::function<bool(const TypeMatcher &, const std::shared_ptr<T> &)>
190 };
191
193
196 }
197
200 }
201
204 }
205
207 m_synth_cont.ForEach(callback.callback);
208 }
209
211 GetFormatForType(lldb::TypeNameSpecifierImplSP type_sp);
212
214 GetSummaryForType(lldb::TypeNameSpecifierImplSP type_sp);
215
217 GetFilterForType(lldb::TypeNameSpecifierImplSP type_sp);
218
220 GetSyntheticForType(lldb::TypeNameSpecifierImplSP type_sp);
221
222 void AddTypeFormat(lldb::TypeNameSpecifierImplSP type_sp,
223 lldb::TypeFormatImplSP format_sp) {
224 m_format_cont.Add(type_sp, format_sp);
225 }
226
227 void AddTypeFormat(llvm::StringRef name, lldb::FormatterMatchType match_type,
228 lldb::TypeFormatImplSP format_sp) {
230 std::make_shared<lldb_private::TypeNameSpecifierImpl>(name, match_type),
231 format_sp);
232 }
233
234 void AddTypeSummary(lldb::TypeNameSpecifierImplSP type_sp,
235 lldb::TypeSummaryImplSP summary_sp) {
236 m_summary_cont.Add(type_sp, summary_sp);
237 }
238
239 void AddTypeSummary(llvm::StringRef name, lldb::FormatterMatchType match_type,
240 lldb::TypeSummaryImplSP summary_sp) {
242 std::make_shared<lldb_private::TypeNameSpecifierImpl>(name, match_type),
243 summary_sp);
244 }
245
246 void AddTypeFilter(lldb::TypeNameSpecifierImplSP type_sp,
247 lldb::TypeFilterImplSP filter_sp) {
248 m_filter_cont.Add(type_sp, filter_sp);
249 }
250
251 void AddTypeFilter(llvm::StringRef name, lldb::FormatterMatchType match_type,
252 lldb::TypeFilterImplSP filter_sp) {
254 std::make_shared<lldb_private::TypeNameSpecifierImpl>(name, match_type),
255 filter_sp);
256 }
257
258 void AddTypeSynthetic(lldb::TypeNameSpecifierImplSP type_sp,
259 lldb::SyntheticChildrenSP synth_sp) {
260 m_synth_cont.Add(type_sp, synth_sp);
261 }
262
263 void AddTypeSynthetic(llvm::StringRef name,
264 lldb::FormatterMatchType match_type,
265 lldb::SyntheticChildrenSP synth_sp) {
267 std::make_shared<lldb_private::TypeNameSpecifierImpl>(name, match_type),
268 synth_sp);
269 }
270
271 bool DeleteTypeFormat(lldb::TypeNameSpecifierImplSP type_sp) {
272 return m_format_cont.Delete(type_sp);
273 }
274
275 bool DeleteTypeSummary(lldb::TypeNameSpecifierImplSP type_sp) {
276 return m_summary_cont.Delete(type_sp);
277 }
278
279 bool DeleteTypeFilter(lldb::TypeNameSpecifierImplSP type_sp) {
280 return m_filter_cont.Delete(type_sp);
281 }
282
283 bool DeleteTypeSynthetic(lldb::TypeNameSpecifierImplSP type_sp) {
284 return m_synth_cont.Delete(type_sp);
285 }
286
288
290
292
294
295 lldb::TypeNameSpecifierImplSP
297
298 lldb::TypeNameSpecifierImplSP
300
301 lldb::TypeNameSpecifierImplSP
303
304 lldb::TypeNameSpecifierImplSP
306
308
310
312
314
315 bool IsEnabled() const { return m_enabled; }
316
318 if (!m_enabled)
319 return UINT32_MAX;
320 else
321 return m_enabled_position;
322 }
323
324 bool Get(lldb::LanguageType lang, const FormattersMatchVector &candidates,
325 lldb::TypeFormatImplSP &entry);
326
327 bool Get(lldb::LanguageType lang, const FormattersMatchVector &candidates,
328 lldb::TypeSummaryImplSP &entry);
329
330 bool Get(lldb::LanguageType lang, const FormattersMatchVector &candidates,
331 lldb::SyntheticChildrenSP &entry);
332
334
336
338
339 const char *GetName() { return m_name.GetCString(); }
340
341 size_t GetNumLanguages();
342
344
346
347 std::string GetDescription();
348
349 bool AnyMatches(const FormattersMatchCandidate &candidate_type,
351 bool only_enabled = true,
352 const char **matching_category = nullptr,
353 FormatCategoryItems *matching_type = nullptr);
354
356
357 typedef std::shared_ptr<TypeCategoryImpl> SharedPointer;
358
359private:
364
366
368
369 std::recursive_mutex m_mutex;
370
372
373 std::vector<lldb::LanguageType> m_languages;
374
376
377 void Enable(bool value, uint32_t position);
378
379 void Disable() { Enable(false, UINT32_MAX); }
380
382
384
386
387 friend class FormatManager;
388 friend class LanguageCategory;
389 friend class TypeCategoryMap;
390
392
394
396
398};
399
400} // namespace lldb_private
401
402#endif // LLDB_DATAFORMATTERS_TYPECATEGORY_H
"lldb/Utility/ArgCompletionRequest.h"
A uniqued constant string class.
Definition: ConstString.h:39
const char * GetCString() const
Get the string value as a C string.
Definition: ConstString.h:215
std::shared_ptr< ValueType > ValueSP
std::function< bool(const TypeMatcher &, const ValueSP &)> ForEachCallback
void AutoComplete(CompletionRequest &request)
Definition: TypeCategory.h:157
typename Subcontainer::ForEachCallback ForEachCallback
Definition: TypeCategory.h:40
void ForEach(std::function< bool(const TypeMatcher &, const std::shared_ptr< FormatterImpl > &)> callback)
Iterates through tiers in order, running callback on each element of each tier.
Definition: TypeCategory.h:149
MapValueType GetAtIndex(size_t index)
Returns the formatter at index, simulating a flattened view of all subcontainers in priority order.
Definition: TypeCategory.h:87
bool Get(const FormattersMatchVector &candidates, std::shared_ptr< FormatterImpl > &entry)
Looks for a matching candidate across all priority tiers, in priority order.
Definition: TypeCategory.h:99
void Clear()
Clears all subcontainers.
Definition: TypeCategory.h:49
lldb::TypeNameSpecifierImplSP GetTypeNameSpecifierAtIndex(size_t index)
Returns the type name specifier at index, simulating a flattened view of all subcontainers in priorit...
Definition: TypeCategory.h:138
std::array< std::shared_ptr< Subcontainer >, lldb::eLastFormatterMatchType+1 > m_subcontainers
Definition: TypeCategory.h:164
typename Subcontainer::ValueSP MapValueType
Definition: TypeCategory.h:41
void Add(lldb::TypeNameSpecifierImplSP type_sp, std::shared_ptr< FormatterImpl > format_sp)
Adds a formatter to the right subcontainer depending on the matching type specified by type_sp.
Definition: TypeCategory.h:56
bool Delete(ConstString name)
Deletes all formatters registered with the string name, in all subcontainers.
Definition: TypeCategory.h:70
bool Delete(lldb::TypeNameSpecifierImplSP type_sp)
Deletes the formatter specified by type_sp.
Definition: TypeCategory.h:63
MapValueType GetForTypeNameSpecifier(lldb::TypeNameSpecifierImplSP type_specifier_sp)
Returns a formatter that is an exact match for type_specifier_sp.
Definition: TypeCategory.h:127
uint32_t GetCount()
Returns the total count of elements across all subcontainers.
Definition: TypeCategory.h:78
std::shared_ptr< Subcontainer > SubcontainerSP
Definition: TypeCategory.h:39
TieredFormatterContainer(IFormatChangeListener *change_listener)
Definition: TypeCategory.h:43
bool AnyMatches(const FormattersMatchCandidate &candidate)
Definition: TypeCategory.h:108
void AddTypeFormat(lldb::TypeNameSpecifierImplSP type_sp, lldb::TypeFormatImplSP format_sp)
Definition: TypeCategory.h:222
uint32_t GetCount(FormatCategoryItems items=ALL_ITEM_TYPES)
bool DeleteTypeFormat(lldb::TypeNameSpecifierImplSP type_sp)
Definition: TypeCategory.h:271
SummaryContainer::MapValueType GetSummaryAtIndex(size_t index)
TieredFormatterContainer< TypeFilterImpl > FilterContainer
Definition: TypeCategory.h:171
void AddTypeSummary(lldb::TypeNameSpecifierImplSP type_sp, lldb::TypeSummaryImplSP summary_sp)
Definition: TypeCategory.h:234
static const uint16_t ALL_ITEM_TYPES
Definition: TypeCategory.h:176
lldb::TypeNameSpecifierImplSP GetTypeNameSpecifierForSyntheticAtIndex(size_t index)
void AddTypeSynthetic(llvm::StringRef name, lldb::FormatterMatchType match_type, lldb::SyntheticChildrenSP synth_sp)
Definition: TypeCategory.h:263
SummaryContainer::MapValueType GetSummaryForType(lldb::TypeNameSpecifierImplSP type_sp)
FilterContainer::MapValueType GetFilterForType(lldb::TypeNameSpecifierImplSP type_sp)
TieredFormatterContainer< TypeFormatImpl > FormatContainer
Definition: TypeCategory.h:169
lldb::TypeNameSpecifierImplSP GetTypeNameSpecifierForSummaryAtIndex(size_t index)
lldb::TypeNameSpecifierImplSP GetTypeNameSpecifierForFormatAtIndex(size_t index)
bool Get(lldb::LanguageType lang, const FormattersMatchVector &candidates, lldb::TypeFormatImplSP &entry)
void AddTypeSummary(llvm::StringRef name, lldb::FormatterMatchType match_type, lldb::TypeSummaryImplSP summary_sp)
Definition: TypeCategory.h:239
lldb::TypeNameSpecifierImplSP GetTypeNameSpecifierForFilterAtIndex(size_t index)
void ForEach(ForEachCallback< TypeSummaryImpl > callback)
Definition: TypeCategory.h:198
void AddTypeFormat(llvm::StringRef name, lldb::FormatterMatchType match_type, lldb::TypeFormatImplSP format_sp)
Definition: TypeCategory.h:227
void ForEach(ForEachCallback< TypeFilterImpl > callback)
Definition: TypeCategory.h:202
FormatContainer::MapValueType GetFormatAtIndex(size_t index)
void AddTypeFilter(lldb::TypeNameSpecifierImplSP type_sp, lldb::TypeFilterImplSP filter_sp)
Definition: TypeCategory.h:246
IFormatChangeListener * m_change_listener
Definition: TypeCategory.h:367
std::recursive_mutex m_mutex
Definition: TypeCategory.h:369
void AddLanguage(lldb::LanguageType lang)
lldb::LanguageType GetLanguageAtIndex(size_t idx)
void AddTypeFilter(llvm::StringRef name, lldb::FormatterMatchType match_type, lldb::TypeFilterImplSP filter_sp)
Definition: TypeCategory.h:251
bool DeleteTypeSynthetic(lldb::TypeNameSpecifierImplSP type_sp)
Definition: TypeCategory.h:283
bool DeleteTypeSummary(lldb::TypeNameSpecifierImplSP type_sp)
Definition: TypeCategory.h:275
TieredFormatterContainer< TypeSummaryImpl > SummaryContainer
Definition: TypeCategory.h:170
bool AnyMatches(const FormattersMatchCandidate &candidate_type, FormatCategoryItems items=ALL_ITEM_TYPES, bool only_enabled=true, const char **matching_category=nullptr, FormatCategoryItems *matching_type=nullptr)
void ForEach(ForEachCallback< TypeFormatImpl > callback)
Definition: TypeCategory.h:194
bool Delete(ConstString name, FormatCategoryItems items=ALL_ITEM_TYPES)
SummaryContainer m_summary_cont
Definition: TypeCategory.h:361
void AutoComplete(CompletionRequest &request, FormatCategoryItems items)
void AddTypeSynthetic(lldb::TypeNameSpecifierImplSP type_sp, lldb::SyntheticChildrenSP synth_sp)
Definition: TypeCategory.h:258
FilterContainer::MapValueType GetFilterAtIndex(size_t index)
SynthContainer::MapValueType GetSyntheticAtIndex(size_t index)
bool IsApplicable(lldb::LanguageType lang)
void SetEnabledPosition(uint32_t p)
Definition: TypeCategory.h:385
bool DeleteTypeFilter(lldb::TypeNameSpecifierImplSP type_sp)
Definition: TypeCategory.h:279
FormatContainer::MapValueType GetFormatForType(lldb::TypeNameSpecifierImplSP type_sp)
std::vector< lldb::LanguageType > m_languages
Definition: TypeCategory.h:373
std::shared_ptr< TypeCategoryImpl > SharedPointer
Definition: TypeCategory.h:357
void Clear(FormatCategoryItems items=ALL_ITEM_TYPES)
SynthContainer::MapValueType GetSyntheticForType(lldb::TypeNameSpecifierImplSP type_sp)
void ForEach(ForEachCallback< SyntheticChildren > callback)
Definition: TypeCategory.h:206
void Enable(bool value, uint32_t position)
TieredFormatterContainer< SyntheticChildren > SynthContainer
Definition: TypeCategory.h:172
Class for matching type names.
#define UINT32_MAX
Definition: lldb-defines.h:19
A class that represents a running process on the host machine.
std::vector< FormattersMatchCandidate > FormattersMatchVector
LanguageType
Programming language type.
FormatterMatchType
Type of match to be performed when looking for a formatter for a data type.
@ eLastFormatterMatchType
std::function< bool(const TypeMatcher &, const std::shared_ptr< T > &)> callback
Definition: TypeCategory.h:189