| //===-- FormatManager.h -----------------------------------------*- C++ -*-===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef lldb_FormatManager_h_ |
| #define lldb_FormatManager_h_ |
| |
| // C Includes |
| // C++ Includes |
| #include <atomic> |
| #include <initializer_list> |
| #include <map> |
| #include <mutex> |
| #include <vector> |
| |
| // Other libraries and framework includes |
| // Project includes |
| #include "lldb/lldb-enumerations.h" |
| #include "lldb/lldb-public.h" |
| |
| #include "lldb/DataFormatters/FormatCache.h" |
| #include "lldb/DataFormatters/FormatClasses.h" |
| #include "lldb/DataFormatters/FormattersContainer.h" |
| #include "lldb/DataFormatters/LanguageCategory.h" |
| #include "lldb/DataFormatters/TypeCategory.h" |
| #include "lldb/DataFormatters/TypeCategoryMap.h" |
| |
| namespace lldb_private { |
| |
| // this file (and its. cpp) contain the low-level implementation of LLDB Data |
| // Visualization class DataVisualization is the high-level front-end of this |
| // feature clients should refer to that class as the entry-point into the data |
| // formatters unless they have a good reason to bypass it and prefer to use |
| // this file's objects directly |
| |
| class FormatManager : public IFormatChangeListener { |
| typedef FormatMap<ConstString, TypeSummaryImpl> NamedSummariesMap; |
| typedef TypeCategoryMap::MapType::iterator CategoryMapIterator; |
| |
| public: |
| typedef std::map<lldb::LanguageType, LanguageCategory::UniquePointer> |
| LanguageCategories; |
| |
| FormatManager(); |
| |
| ~FormatManager() override = default; |
| |
| NamedSummariesMap &GetNamedSummaryContainer() { |
| return m_named_summaries_map; |
| } |
| |
| void |
| EnableCategory(const ConstString &category_name, |
| TypeCategoryMap::Position pos = TypeCategoryMap::Default) { |
| EnableCategory(category_name, pos, |
| std::initializer_list<lldb::LanguageType>()); |
| } |
| |
| void EnableCategory(const ConstString &category_name, |
| TypeCategoryMap::Position pos, lldb::LanguageType lang) { |
| std::initializer_list<lldb::LanguageType> langs = {lang}; |
| EnableCategory(category_name, pos, langs); |
| } |
| |
| void EnableCategory(const ConstString &category_name, |
| TypeCategoryMap::Position pos = TypeCategoryMap::Default, |
| std::initializer_list<lldb::LanguageType> langs = {}) { |
| TypeCategoryMap::ValueSP category_sp; |
| if (m_categories_map.Get(category_name, category_sp) && category_sp) { |
| m_categories_map.Enable(category_sp, pos); |
| for (const lldb::LanguageType lang : langs) |
| category_sp->AddLanguage(lang); |
| } |
| } |
| |
| void DisableCategory(const ConstString &category_name) { |
| m_categories_map.Disable(category_name); |
| } |
| |
| void |
| EnableCategory(const lldb::TypeCategoryImplSP &category, |
| TypeCategoryMap::Position pos = TypeCategoryMap::Default) { |
| m_categories_map.Enable(category, pos); |
| } |
| |
| void DisableCategory(const lldb::TypeCategoryImplSP &category) { |
| m_categories_map.Disable(category); |
| } |
| |
| void EnableAllCategories(); |
| |
| void DisableAllCategories(); |
| |
| bool DeleteCategory(const ConstString &category_name) { |
| return m_categories_map.Delete(category_name); |
| } |
| |
| void ClearCategories() { return m_categories_map.Clear(); } |
| |
| uint32_t GetCategoriesCount() { return m_categories_map.GetCount(); } |
| |
| lldb::TypeCategoryImplSP GetCategoryAtIndex(size_t index) { |
| return m_categories_map.GetAtIndex(index); |
| } |
| |
| void ForEachCategory(TypeCategoryMap::ForEachCallback callback); |
| |
| lldb::TypeCategoryImplSP GetCategory(const char *category_name = nullptr, |
| bool can_create = true) { |
| if (!category_name) |
| return GetCategory(m_default_category_name); |
| return GetCategory(ConstString(category_name)); |
| } |
| |
| lldb::TypeCategoryImplSP GetCategory(const ConstString &category_name, |
| bool can_create = true); |
| |
| lldb::TypeFormatImplSP |
| GetFormatForType(lldb::TypeNameSpecifierImplSP type_sp); |
| |
| lldb::TypeSummaryImplSP |
| GetSummaryForType(lldb::TypeNameSpecifierImplSP type_sp); |
| |
| lldb::TypeFilterImplSP |
| GetFilterForType(lldb::TypeNameSpecifierImplSP type_sp); |
| |
| #ifndef LLDB_DISABLE_PYTHON |
| lldb::ScriptedSyntheticChildrenSP |
| GetSyntheticForType(lldb::TypeNameSpecifierImplSP type_sp); |
| #endif |
| |
| #ifndef LLDB_DISABLE_PYTHON |
| lldb::SyntheticChildrenSP |
| GetSyntheticChildrenForType(lldb::TypeNameSpecifierImplSP type_sp); |
| #endif |
| |
| lldb::TypeValidatorImplSP |
| GetValidatorForType(lldb::TypeNameSpecifierImplSP type_sp); |
| |
| lldb::TypeFormatImplSP GetFormat(ValueObject &valobj, |
| lldb::DynamicValueType use_dynamic); |
| |
| lldb::TypeSummaryImplSP GetSummaryFormat(ValueObject &valobj, |
| lldb::DynamicValueType use_dynamic); |
| |
| #ifndef LLDB_DISABLE_PYTHON |
| lldb::SyntheticChildrenSP |
| GetSyntheticChildren(ValueObject &valobj, lldb::DynamicValueType use_dynamic); |
| #endif |
| |
| lldb::TypeValidatorImplSP GetValidator(ValueObject &valobj, |
| lldb::DynamicValueType use_dynamic); |
| |
| bool |
| AnyMatches(ConstString type_name, |
| TypeCategoryImpl::FormatCategoryItems items = |
| TypeCategoryImpl::ALL_ITEM_TYPES, |
| bool only_enabled = true, const char **matching_category = nullptr, |
| TypeCategoryImpl::FormatCategoryItems *matching_type = nullptr) { |
| return m_categories_map.AnyMatches(type_name, items, only_enabled, |
| matching_category, matching_type); |
| } |
| |
| static bool GetFormatFromCString(const char *format_cstr, |
| bool partial_match_ok, lldb::Format &format); |
| |
| static char GetFormatAsFormatChar(lldb::Format format); |
| |
| static const char *GetFormatAsCString(lldb::Format format); |
| |
| // if the user tries to add formatters for, say, "struct Foo" those will not |
| // match any type because of the way we strip qualifiers from typenames this |
| // method looks for the case where the user is adding a |
| // "class","struct","enum" or "union" Foo and strips the unnecessary |
| // qualifier |
| static ConstString GetValidTypeName(const ConstString &type); |
| |
| // when DataExtractor dumps a vectorOfT, it uses a predefined format for each |
| // item this method returns it, or eFormatInvalid if vector_format is not a |
| // vectorOf |
| static lldb::Format GetSingleItemFormat(lldb::Format vector_format); |
| |
| // this returns true if the ValueObjectPrinter is *highly encouraged* to |
| // actually represent this ValueObject in one-liner format If this object has |
| // a summary formatter, however, we should not try and do one-lining, just |
| // let the summary do the right thing |
| bool ShouldPrintAsOneLiner(ValueObject &valobj); |
| |
| void Changed() override; |
| |
| uint32_t GetCurrentRevision() override { return m_last_revision; } |
| |
| static FormattersMatchVector |
| GetPossibleMatches(ValueObject &valobj, lldb::DynamicValueType use_dynamic) { |
| FormattersMatchVector matches; |
| GetPossibleMatches(valobj, valobj.GetCompilerType(), |
| lldb_private::eFormatterChoiceCriterionDirectChoice, |
| use_dynamic, matches, false, false, false, true); |
| return matches; |
| } |
| |
| static ConstString GetTypeForCache(ValueObject &, lldb::DynamicValueType); |
| |
| LanguageCategory *GetCategoryForLanguage(lldb::LanguageType lang_type); |
| |
| static std::vector<lldb::LanguageType> |
| GetCandidateLanguages(lldb::LanguageType lang_type); |
| |
| private: |
| static std::vector<lldb::LanguageType> |
| GetCandidateLanguages(ValueObject &valobj); |
| |
| static void GetPossibleMatches(ValueObject &valobj, |
| CompilerType compiler_type, uint32_t reason, |
| lldb::DynamicValueType use_dynamic, |
| FormattersMatchVector &entries, |
| bool did_strip_ptr, bool did_strip_ref, |
| bool did_strip_typedef, |
| bool root_level = false); |
| |
| std::atomic<uint32_t> m_last_revision; |
| FormatCache m_format_cache; |
| std::recursive_mutex m_language_categories_mutex; |
| LanguageCategories m_language_categories_map; |
| NamedSummariesMap m_named_summaries_map; |
| TypeCategoryMap m_categories_map; |
| |
| ConstString m_default_category_name; |
| ConstString m_system_category_name; |
| ConstString m_vectortypes_category_name; |
| |
| lldb::TypeFormatImplSP GetHardcodedFormat(FormattersMatchData &); |
| |
| lldb::TypeSummaryImplSP GetHardcodedSummaryFormat(FormattersMatchData &); |
| |
| lldb::SyntheticChildrenSP |
| GetHardcodedSyntheticChildren(FormattersMatchData &); |
| |
| lldb::TypeValidatorImplSP GetHardcodedValidator(FormattersMatchData &); |
| |
| TypeCategoryMap &GetCategories() { return m_categories_map; } |
| |
| // These functions are meant to initialize formatters that are very low- |
| // level/global in nature and do not naturally belong in any language. The |
| // intent is that most formatters go in language-specific categories. |
| // Eventually, the runtimes should also be allowed to vend their own |
| // formatters, and then one could put formatters that depend on specific |
| // library load events in the language runtimes, on an as-needed basis |
| void LoadSystemFormatters(); |
| |
| void LoadVectorFormatters(); |
| |
| friend class FormattersMatchData; |
| }; |
| |
| } // namespace lldb_private |
| |
| #endif // lldb_FormatManager_h_ |