xref: /freebsd/contrib/llvm-project/lldb/include/lldb/DataFormatters/FormatManager.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===-- FormatManager.h -----------------------------------------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
95ffd83dbSDimitry Andric #ifndef LLDB_DATAFORMATTERS_FORMATMANAGER_H
105ffd83dbSDimitry Andric #define LLDB_DATAFORMATTERS_FORMATMANAGER_H
110b57cec5SDimitry Andric 
120b57cec5SDimitry Andric #include <atomic>
130b57cec5SDimitry Andric #include <initializer_list>
140b57cec5SDimitry Andric #include <map>
150b57cec5SDimitry Andric #include <mutex>
160b57cec5SDimitry Andric #include <vector>
170b57cec5SDimitry Andric 
180b57cec5SDimitry Andric #include "lldb/lldb-enumerations.h"
190b57cec5SDimitry Andric #include "lldb/lldb-public.h"
200b57cec5SDimitry Andric 
210b57cec5SDimitry Andric #include "lldb/DataFormatters/FormatCache.h"
220b57cec5SDimitry Andric #include "lldb/DataFormatters/FormatClasses.h"
230b57cec5SDimitry Andric #include "lldb/DataFormatters/FormattersContainer.h"
240b57cec5SDimitry Andric #include "lldb/DataFormatters/LanguageCategory.h"
250b57cec5SDimitry Andric #include "lldb/DataFormatters/TypeCategory.h"
260b57cec5SDimitry Andric #include "lldb/DataFormatters/TypeCategoryMap.h"
270b57cec5SDimitry Andric 
280b57cec5SDimitry Andric namespace lldb_private {
290b57cec5SDimitry Andric 
300b57cec5SDimitry Andric // this file (and its. cpp) contain the low-level implementation of LLDB Data
310b57cec5SDimitry Andric // Visualization class DataVisualization is the high-level front-end of this
320b57cec5SDimitry Andric // feature clients should refer to that class as the entry-point into the data
330b57cec5SDimitry Andric // formatters unless they have a good reason to bypass it and prefer to use
340b57cec5SDimitry Andric // this file's objects directly
350b57cec5SDimitry Andric 
360b57cec5SDimitry Andric class FormatManager : public IFormatChangeListener {
37e8d8bef9SDimitry Andric   typedef FormattersContainer<TypeSummaryImpl> NamedSummariesMap;
380b57cec5SDimitry Andric   typedef TypeCategoryMap::MapType::iterator CategoryMapIterator;
390b57cec5SDimitry Andric 
400b57cec5SDimitry Andric public:
410b57cec5SDimitry Andric   typedef std::map<lldb::LanguageType, LanguageCategory::UniquePointer>
420b57cec5SDimitry Andric       LanguageCategories;
430b57cec5SDimitry Andric 
440b57cec5SDimitry Andric   FormatManager();
450b57cec5SDimitry Andric 
460b57cec5SDimitry Andric   ~FormatManager() override = default;
470b57cec5SDimitry Andric 
GetNamedSummaryContainer()480b57cec5SDimitry Andric   NamedSummariesMap &GetNamedSummaryContainer() {
490b57cec5SDimitry Andric     return m_named_summaries_map;
500b57cec5SDimitry Andric   }
510b57cec5SDimitry Andric 
520b57cec5SDimitry Andric   void
530b57cec5SDimitry Andric   EnableCategory(ConstString category_name,
540b57cec5SDimitry Andric                  TypeCategoryMap::Position pos = TypeCategoryMap::Default) {
55480093f4SDimitry Andric     EnableCategory(category_name, pos, {});
560b57cec5SDimitry Andric   }
570b57cec5SDimitry Andric 
EnableCategory(ConstString category_name,TypeCategoryMap::Position pos,lldb::LanguageType lang)580b57cec5SDimitry Andric   void EnableCategory(ConstString category_name,
590b57cec5SDimitry Andric                       TypeCategoryMap::Position pos, lldb::LanguageType lang) {
605f757f3fSDimitry Andric     lldb::TypeCategoryImplSP category_sp;
610b57cec5SDimitry Andric     if (m_categories_map.Get(category_name, category_sp) && category_sp) {
620b57cec5SDimitry Andric       m_categories_map.Enable(category_sp, pos);
630b57cec5SDimitry Andric       category_sp->AddLanguage(lang);
640b57cec5SDimitry Andric     }
650b57cec5SDimitry Andric   }
660b57cec5SDimitry Andric 
DisableCategory(ConstString category_name)670b57cec5SDimitry Andric   void DisableCategory(ConstString category_name) {
680b57cec5SDimitry Andric     m_categories_map.Disable(category_name);
690b57cec5SDimitry Andric   }
700b57cec5SDimitry Andric 
710b57cec5SDimitry Andric   void
720b57cec5SDimitry Andric   EnableCategory(const lldb::TypeCategoryImplSP &category,
730b57cec5SDimitry Andric                  TypeCategoryMap::Position pos = TypeCategoryMap::Default) {
740b57cec5SDimitry Andric     m_categories_map.Enable(category, pos);
750b57cec5SDimitry Andric   }
760b57cec5SDimitry Andric 
DisableCategory(const lldb::TypeCategoryImplSP & category)770b57cec5SDimitry Andric   void DisableCategory(const lldb::TypeCategoryImplSP &category) {
780b57cec5SDimitry Andric     m_categories_map.Disable(category);
790b57cec5SDimitry Andric   }
800b57cec5SDimitry Andric 
810b57cec5SDimitry Andric   void EnableAllCategories();
820b57cec5SDimitry Andric 
830b57cec5SDimitry Andric   void DisableAllCategories();
840b57cec5SDimitry Andric 
DeleteCategory(ConstString category_name)850b57cec5SDimitry Andric   bool DeleteCategory(ConstString category_name) {
860b57cec5SDimitry Andric     return m_categories_map.Delete(category_name);
870b57cec5SDimitry Andric   }
880b57cec5SDimitry Andric 
ClearCategories()890b57cec5SDimitry Andric   void ClearCategories() { return m_categories_map.Clear(); }
900b57cec5SDimitry Andric 
GetCategoriesCount()910b57cec5SDimitry Andric   uint32_t GetCategoriesCount() { return m_categories_map.GetCount(); }
920b57cec5SDimitry Andric 
GetCategoryAtIndex(size_t index)930b57cec5SDimitry Andric   lldb::TypeCategoryImplSP GetCategoryAtIndex(size_t index) {
940b57cec5SDimitry Andric     return m_categories_map.GetAtIndex(index);
950b57cec5SDimitry Andric   }
960b57cec5SDimitry Andric 
970b57cec5SDimitry Andric   void ForEachCategory(TypeCategoryMap::ForEachCallback callback);
980b57cec5SDimitry Andric 
990b57cec5SDimitry Andric   lldb::TypeCategoryImplSP GetCategory(const char *category_name = nullptr,
1000b57cec5SDimitry Andric                                        bool can_create = true) {
1010b57cec5SDimitry Andric     if (!category_name)
1020b57cec5SDimitry Andric       return GetCategory(m_default_category_name);
1030b57cec5SDimitry Andric     return GetCategory(ConstString(category_name));
1040b57cec5SDimitry Andric   }
1050b57cec5SDimitry Andric 
1060b57cec5SDimitry Andric   lldb::TypeCategoryImplSP GetCategory(ConstString category_name,
1070b57cec5SDimitry Andric                                        bool can_create = true);
1080b57cec5SDimitry Andric 
1090b57cec5SDimitry Andric   lldb::TypeFormatImplSP
1100b57cec5SDimitry Andric   GetFormatForType(lldb::TypeNameSpecifierImplSP type_sp);
1110b57cec5SDimitry Andric 
1120b57cec5SDimitry Andric   lldb::TypeSummaryImplSP
1130b57cec5SDimitry Andric   GetSummaryForType(lldb::TypeNameSpecifierImplSP type_sp);
1140b57cec5SDimitry Andric 
1150b57cec5SDimitry Andric   lldb::TypeFilterImplSP
1160b57cec5SDimitry Andric   GetFilterForType(lldb::TypeNameSpecifierImplSP type_sp);
1170b57cec5SDimitry Andric 
1180b57cec5SDimitry Andric   lldb::ScriptedSyntheticChildrenSP
1190b57cec5SDimitry Andric   GetSyntheticForType(lldb::TypeNameSpecifierImplSP type_sp);
1200b57cec5SDimitry Andric 
1210b57cec5SDimitry Andric   lldb::TypeFormatImplSP GetFormat(ValueObject &valobj,
1220b57cec5SDimitry Andric                                    lldb::DynamicValueType use_dynamic);
1230b57cec5SDimitry Andric 
1240b57cec5SDimitry Andric   lldb::TypeSummaryImplSP GetSummaryFormat(ValueObject &valobj,
1250b57cec5SDimitry Andric                                            lldb::DynamicValueType use_dynamic);
1260b57cec5SDimitry Andric 
1270b57cec5SDimitry Andric   lldb::SyntheticChildrenSP
1280b57cec5SDimitry Andric   GetSyntheticChildren(ValueObject &valobj, lldb::DynamicValueType use_dynamic);
1290b57cec5SDimitry Andric 
1300b57cec5SDimitry Andric   bool
131bdd1243dSDimitry Andric   AnyMatches(const FormattersMatchCandidate &candidate_type,
1320b57cec5SDimitry Andric              TypeCategoryImpl::FormatCategoryItems items =
1330b57cec5SDimitry Andric                  TypeCategoryImpl::ALL_ITEM_TYPES,
1340b57cec5SDimitry Andric              bool only_enabled = true, const char **matching_category = nullptr,
1350b57cec5SDimitry Andric              TypeCategoryImpl::FormatCategoryItems *matching_type = nullptr) {
136bdd1243dSDimitry Andric     return m_categories_map.AnyMatches(candidate_type, items, only_enabled,
1370b57cec5SDimitry Andric                                        matching_category, matching_type);
1380b57cec5SDimitry Andric   }
1390b57cec5SDimitry Andric 
1400b57cec5SDimitry Andric   static bool GetFormatFromCString(const char *format_cstr,
141*0fca6ea1SDimitry Andric                                    lldb::Format &format);
1420b57cec5SDimitry Andric 
1430b57cec5SDimitry Andric   static char GetFormatAsFormatChar(lldb::Format format);
1440b57cec5SDimitry Andric 
1450b57cec5SDimitry Andric   static const char *GetFormatAsCString(lldb::Format format);
1460b57cec5SDimitry Andric 
1470b57cec5SDimitry Andric   // when DataExtractor dumps a vectorOfT, it uses a predefined format for each
1480b57cec5SDimitry Andric   // item this method returns it, or eFormatInvalid if vector_format is not a
1490b57cec5SDimitry Andric   // vectorOf
1500b57cec5SDimitry Andric   static lldb::Format GetSingleItemFormat(lldb::Format vector_format);
1510b57cec5SDimitry Andric 
1520b57cec5SDimitry Andric   // this returns true if the ValueObjectPrinter is *highly encouraged* to
1530b57cec5SDimitry Andric   // actually represent this ValueObject in one-liner format If this object has
1540b57cec5SDimitry Andric   // a summary formatter, however, we should not try and do one-lining, just
1550b57cec5SDimitry Andric   // let the summary do the right thing
1560b57cec5SDimitry Andric   bool ShouldPrintAsOneLiner(ValueObject &valobj);
1570b57cec5SDimitry Andric 
1580b57cec5SDimitry Andric   void Changed() override;
1590b57cec5SDimitry Andric 
GetCurrentRevision()1600b57cec5SDimitry Andric   uint32_t GetCurrentRevision() override { return m_last_revision; }
1610b57cec5SDimitry Andric 
1620b57cec5SDimitry Andric   static FormattersMatchVector
GetPossibleMatches(ValueObject & valobj,lldb::DynamicValueType use_dynamic)1630b57cec5SDimitry Andric   GetPossibleMatches(ValueObject &valobj, lldb::DynamicValueType use_dynamic) {
1640b57cec5SDimitry Andric     FormattersMatchVector matches;
165bdd1243dSDimitry Andric     GetPossibleMatches(valobj, valobj.GetCompilerType(), use_dynamic, matches,
166bdd1243dSDimitry Andric                        FormattersMatchCandidate::Flags(), true);
1670b57cec5SDimitry Andric     return matches;
1680b57cec5SDimitry Andric   }
1690b57cec5SDimitry Andric 
1700b57cec5SDimitry Andric   static ConstString GetTypeForCache(ValueObject &, lldb::DynamicValueType);
1710b57cec5SDimitry Andric 
1720b57cec5SDimitry Andric   LanguageCategory *GetCategoryForLanguage(lldb::LanguageType lang_type);
1730b57cec5SDimitry Andric 
1740b57cec5SDimitry Andric   static std::vector<lldb::LanguageType>
1750b57cec5SDimitry Andric   GetCandidateLanguages(lldb::LanguageType lang_type);
1760b57cec5SDimitry Andric 
1770b57cec5SDimitry Andric private:
1780b57cec5SDimitry Andric   static void GetPossibleMatches(ValueObject &valobj,
1795ffd83dbSDimitry Andric                                  CompilerType compiler_type,
1800b57cec5SDimitry Andric                                  lldb::DynamicValueType use_dynamic,
1810b57cec5SDimitry Andric                                  FormattersMatchVector &entries,
182bdd1243dSDimitry Andric                                  FormattersMatchCandidate::Flags current_flags,
1830b57cec5SDimitry Andric                                  bool root_level = false);
1840b57cec5SDimitry Andric 
1850b57cec5SDimitry Andric   std::atomic<uint32_t> m_last_revision;
1860b57cec5SDimitry Andric   FormatCache m_format_cache;
1870b57cec5SDimitry Andric   std::recursive_mutex m_language_categories_mutex;
1880b57cec5SDimitry Andric   LanguageCategories m_language_categories_map;
1890b57cec5SDimitry Andric   NamedSummariesMap m_named_summaries_map;
1900b57cec5SDimitry Andric   TypeCategoryMap m_categories_map;
1910b57cec5SDimitry Andric 
1920b57cec5SDimitry Andric   ConstString m_default_category_name;
1930b57cec5SDimitry Andric   ConstString m_system_category_name;
1940b57cec5SDimitry Andric   ConstString m_vectortypes_category_name;
1950b57cec5SDimitry Andric 
196480093f4SDimitry Andric   template <typename ImplSP>
197480093f4SDimitry Andric   ImplSP Get(ValueObject &valobj, lldb::DynamicValueType use_dynamic);
198480093f4SDimitry Andric   template <typename ImplSP> ImplSP GetCached(FormattersMatchData &match_data);
199480093f4SDimitry Andric   template <typename ImplSP> ImplSP GetHardcoded(FormattersMatchData &);
2000b57cec5SDimitry Andric 
GetCategories()2010b57cec5SDimitry Andric   TypeCategoryMap &GetCategories() { return m_categories_map; }
2020b57cec5SDimitry Andric 
2030b57cec5SDimitry Andric   // These functions are meant to initialize formatters that are very low-
2040b57cec5SDimitry Andric   // level/global in nature and do not naturally belong in any language. The
2050b57cec5SDimitry Andric   // intent is that most formatters go in language-specific categories.
2060b57cec5SDimitry Andric   // Eventually, the runtimes should also be allowed to vend their own
2070b57cec5SDimitry Andric   // formatters, and then one could put formatters that depend on specific
2080b57cec5SDimitry Andric   // library load events in the language runtimes, on an as-needed basis
2090b57cec5SDimitry Andric   void LoadSystemFormatters();
2100b57cec5SDimitry Andric 
2110b57cec5SDimitry Andric   void LoadVectorFormatters();
2120b57cec5SDimitry Andric 
2130b57cec5SDimitry Andric   friend class FormattersMatchData;
2140b57cec5SDimitry Andric };
2150b57cec5SDimitry Andric 
2160b57cec5SDimitry Andric } // namespace lldb_private
2170b57cec5SDimitry Andric 
2185ffd83dbSDimitry Andric #endif // LLDB_DATAFORMATTERS_FORMATMANAGER_H
219