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<RegularExpression, 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<SyntheticChildren> SynthContainer; 71 72public: 73 typedef uint16_t FormatCategoryItems; 74 static const uint16_t ALL_ITEM_TYPES = UINT16_MAX; 75 76 typedef FormatContainer::ExactMatchContainerSP FormatContainerSP; 77 typedef FormatContainer::RegexMatchContainerSP RegexFormatContainerSP; 78 79 typedef SummaryContainer::ExactMatchContainerSP SummaryContainerSP; 80 typedef SummaryContainer::RegexMatchContainerSP RegexSummaryContainerSP; 81 82 typedef FilterContainer::ExactMatchContainerSP FilterContainerSP; 83 typedef FilterContainer::RegexMatchContainerSP RegexFilterContainerSP; 84 85 typedef SynthContainer::ExactMatchContainerSP SynthContainerSP; 86 typedef SynthContainer::RegexMatchContainerSP RegexSynthContainerSP; 87 88 template <typename T> class ForEachCallbacks { 89 public: 90 ForEachCallbacks() = default; 91 ~ForEachCallbacks() = default; 92 93 template <typename U = TypeFormatImpl> 94 typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type 95 SetExact(FormatContainer::ExactMatchForEachCallback callback) { 96 m_format_exact = callback; 97 return *this; 98 } 99 template <typename U = TypeFormatImpl> 100 typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type 101 SetWithRegex(FormatContainer::RegexMatchForEachCallback callback) { 102 m_format_regex = callback; 103 return *this; 104 } 105 106 template <typename U = TypeSummaryImpl> 107 typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type 108 SetExact(SummaryContainer::ExactMatchForEachCallback callback) { 109 m_summary_exact = callback; 110 return *this; 111 } 112 template <typename U = TypeSummaryImpl> 113 typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type 114 SetWithRegex(SummaryContainer::RegexMatchForEachCallback callback) { 115 m_summary_regex = callback; 116 return *this; 117 } 118 119 template <typename U = TypeFilterImpl> 120 typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type 121 SetExact(FilterContainer::ExactMatchForEachCallback callback) { 122 m_filter_exact = callback; 123 return *this; 124 } 125 template <typename U = TypeFilterImpl> 126 typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type 127 SetWithRegex(FilterContainer::RegexMatchForEachCallback callback) { 128 m_filter_regex = callback; 129 return *this; 130 } 131 132 template <typename U = SyntheticChildren> 133 typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type 134 SetExact(SynthContainer::ExactMatchForEachCallback callback) { 135 m_synth_exact = callback; 136 return *this; 137 } 138 template <typename U = SyntheticChildren> 139 typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type 140 SetWithRegex(SynthContainer::RegexMatchForEachCallback callback) { 141 m_synth_regex = callback; 142 return *this; 143 } 144 145 FormatContainer::ExactMatchForEachCallback GetFormatExactCallback() const { 146 return m_format_exact; 147 } 148 FormatContainer::RegexMatchForEachCallback GetFormatRegexCallback() const { 149 return m_format_regex; 150 } 151 152 SummaryContainer::ExactMatchForEachCallback 153 GetSummaryExactCallback() const { 154 return m_summary_exact; 155 } 156 SummaryContainer::RegexMatchForEachCallback 157 GetSummaryRegexCallback() const { 158 return m_summary_regex; 159 } 160 161 FilterContainer::ExactMatchForEachCallback GetFilterExactCallback() const { 162 return m_filter_exact; 163 } 164 FilterContainer::RegexMatchForEachCallback GetFilterRegexCallback() const { 165 return m_filter_regex; 166 } 167 168 SynthContainer::ExactMatchForEachCallback GetSynthExactCallback() const { 169 return m_synth_exact; 170 } 171 SynthContainer::RegexMatchForEachCallback GetSynthRegexCallback() const { 172 return m_synth_regex; 173 } 174 175 private: 176 FormatContainer::ExactMatchForEachCallback m_format_exact; 177 FormatContainer::RegexMatchForEachCallback m_format_regex; 178 179 SummaryContainer::ExactMatchForEachCallback m_summary_exact; 180 SummaryContainer::RegexMatchForEachCallback m_summary_regex; 181 182 FilterContainer::ExactMatchForEachCallback m_filter_exact; 183 FilterContainer::RegexMatchForEachCallback m_filter_regex; 184 185 SynthContainer::ExactMatchForEachCallback m_synth_exact; 186 SynthContainer::RegexMatchForEachCallback m_synth_regex; 187 }; 188 189 TypeCategoryImpl(IFormatChangeListener *clist, ConstString name); 190 191 template <typename T> void ForEach(const ForEachCallbacks<T> &foreach) { 192 GetTypeFormatsContainer()->ForEach(foreach.GetFormatExactCallback()); 193 GetRegexTypeFormatsContainer()->ForEach(foreach.GetFormatRegexCallback()); 194 195 GetTypeSummariesContainer()->ForEach(foreach.GetSummaryExactCallback()); 196 GetRegexTypeSummariesContainer()->ForEach( 197 foreach.GetSummaryRegexCallback()); 198 199 GetTypeFiltersContainer()->ForEach(foreach.GetFilterExactCallback()); 200 GetRegexTypeFiltersContainer()->ForEach(foreach.GetFilterRegexCallback()); 201 202 GetTypeSyntheticsContainer()->ForEach(foreach.GetSynthExactCallback()); 203 GetRegexTypeSyntheticsContainer()->ForEach(foreach.GetSynthRegexCallback()); 204 } 205 206 FormatContainerSP GetTypeFormatsContainer() { 207 return m_format_cont.GetExactMatch(); 208 } 209 210 RegexFormatContainerSP GetRegexTypeFormatsContainer() { 211 return m_format_cont.GetRegexMatch(); 212 } 213 214 FormatContainer &GetFormatContainer() { return m_format_cont; } 215 216 SummaryContainerSP GetTypeSummariesContainer() { 217 return m_summary_cont.GetExactMatch(); 218 } 219 220 RegexSummaryContainerSP GetRegexTypeSummariesContainer() { 221 return m_summary_cont.GetRegexMatch(); 222 } 223 224 SummaryContainer &GetSummaryContainer() { return m_summary_cont; } 225 226 FilterContainerSP GetTypeFiltersContainer() { 227 return m_filter_cont.GetExactMatch(); 228 } 229 230 RegexFilterContainerSP GetRegexTypeFiltersContainer() { 231 return m_filter_cont.GetRegexMatch(); 232 } 233 234 FilterContainer &GetFilterContainer() { return m_filter_cont; } 235 236 FormatContainer::MapValueType 237 GetFormatForType(lldb::TypeNameSpecifierImplSP type_sp); 238 239 SummaryContainer::MapValueType 240 GetSummaryForType(lldb::TypeNameSpecifierImplSP type_sp); 241 242 FilterContainer::MapValueType 243 GetFilterForType(lldb::TypeNameSpecifierImplSP type_sp); 244 245 SynthContainer::MapValueType 246 GetSyntheticForType(lldb::TypeNameSpecifierImplSP type_sp); 247 248 lldb::TypeNameSpecifierImplSP 249 GetTypeNameSpecifierForFormatAtIndex(size_t index); 250 251 lldb::TypeNameSpecifierImplSP 252 GetTypeNameSpecifierForSummaryAtIndex(size_t index); 253 254 FormatContainer::MapValueType GetFormatAtIndex(size_t index); 255 256 SummaryContainer::MapValueType GetSummaryAtIndex(size_t index); 257 258 FilterContainer::MapValueType GetFilterAtIndex(size_t index); 259 260 lldb::TypeNameSpecifierImplSP 261 GetTypeNameSpecifierForFilterAtIndex(size_t index); 262 263 SynthContainerSP GetTypeSyntheticsContainer() { 264 return m_synth_cont.GetExactMatch(); 265 } 266 267 RegexSynthContainerSP GetRegexTypeSyntheticsContainer() { 268 return m_synth_cont.GetRegexMatch(); 269 } 270 271 SynthContainer &GetSyntheticsContainer() { return m_synth_cont; } 272 273 SynthContainer::MapValueType GetSyntheticAtIndex(size_t index); 274 275 lldb::TypeNameSpecifierImplSP 276 GetTypeNameSpecifierForSyntheticAtIndex(size_t index); 277 278 bool IsEnabled() const { return m_enabled; } 279 280 uint32_t GetEnabledPosition() { 281 if (!m_enabled) 282 return UINT32_MAX; 283 else 284 return m_enabled_position; 285 } 286 287 bool Get(lldb::LanguageType lang, const FormattersMatchVector &candidates, 288 lldb::TypeFormatImplSP &entry, uint32_t *reason = nullptr); 289 290 bool Get(lldb::LanguageType lang, const FormattersMatchVector &candidates, 291 lldb::TypeSummaryImplSP &entry, uint32_t *reason = nullptr); 292 293 bool Get(lldb::LanguageType lang, const FormattersMatchVector &candidates, 294 lldb::SyntheticChildrenSP &entry, uint32_t *reason = nullptr); 295 296 void Clear(FormatCategoryItems items = ALL_ITEM_TYPES); 297 298 bool Delete(ConstString name, FormatCategoryItems items = ALL_ITEM_TYPES); 299 300 uint32_t GetCount(FormatCategoryItems items = ALL_ITEM_TYPES); 301 302 const char *GetName() { return m_name.GetCString(); } 303 304 size_t GetNumLanguages(); 305 306 lldb::LanguageType GetLanguageAtIndex(size_t idx); 307 308 void AddLanguage(lldb::LanguageType lang); 309 310 std::string GetDescription(); 311 312 bool AnyMatches(ConstString type_name, 313 FormatCategoryItems items = ALL_ITEM_TYPES, 314 bool only_enabled = true, 315 const char **matching_category = nullptr, 316 FormatCategoryItems *matching_type = nullptr); 317 318 typedef std::shared_ptr<TypeCategoryImpl> SharedPointer; 319 320private: 321 FormatContainer m_format_cont; 322 SummaryContainer m_summary_cont; 323 FilterContainer m_filter_cont; 324 SynthContainer m_synth_cont; 325 326 bool m_enabled; 327 328 IFormatChangeListener *m_change_listener; 329 330 std::recursive_mutex m_mutex; 331 332 ConstString m_name; 333 334 std::vector<lldb::LanguageType> m_languages; 335 336 uint32_t m_enabled_position; 337 338 void Enable(bool value, uint32_t position); 339 340 void Disable() { Enable(false, UINT32_MAX); } 341 342 bool IsApplicable(lldb::LanguageType lang); 343 344 uint32_t GetLastEnabledPosition() { return m_enabled_position; } 345 346 void SetEnabledPosition(uint32_t p) { m_enabled_position = p; } 347 348 friend class FormatManager; 349 friend class LanguageCategory; 350 friend class TypeCategoryMap; 351 352 friend class FormattersContainer<ConstString, TypeFormatImpl>; 353 friend class FormattersContainer<lldb::RegularExpressionSP, TypeFormatImpl>; 354 355 friend class FormattersContainer<ConstString, TypeSummaryImpl>; 356 friend class FormattersContainer<lldb::RegularExpressionSP, TypeSummaryImpl>; 357 358 friend class FormattersContainer<ConstString, TypeFilterImpl>; 359 friend class FormattersContainer<lldb::RegularExpressionSP, TypeFilterImpl>; 360 361 friend class FormattersContainer<ConstString, ScriptedSyntheticChildren>; 362 friend class FormattersContainer<lldb::RegularExpressionSP, 363 ScriptedSyntheticChildren>; 364 365}; 366 367} // namespace lldb_private 368 369#endif // lldb_TypeCategory_h_ 370