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