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