10b57cec5SDimitry Andric //===-- FormatClasses.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_FORMATCLASSES_H 105ffd83dbSDimitry Andric #define LLDB_DATAFORMATTERS_FORMATCLASSES_H 110b57cec5SDimitry Andric 120b57cec5SDimitry Andric #include <functional> 130b57cec5SDimitry Andric #include <memory> 140b57cec5SDimitry Andric #include <string> 150b57cec5SDimitry Andric #include <vector> 160b57cec5SDimitry Andric 170b57cec5SDimitry Andric #include "lldb/DataFormatters/TypeFormat.h" 180b57cec5SDimitry Andric #include "lldb/DataFormatters/TypeSummary.h" 190b57cec5SDimitry Andric #include "lldb/DataFormatters/TypeSynthetic.h" 20bdd1243dSDimitry Andric #include "lldb/Interpreter/ScriptInterpreter.h" 210b57cec5SDimitry Andric #include "lldb/Symbol/CompilerType.h" 220b57cec5SDimitry Andric #include "lldb/Symbol/Type.h" 230b57cec5SDimitry Andric #include "lldb/lldb-enumerations.h" 240b57cec5SDimitry Andric #include "lldb/lldb-public.h" 250b57cec5SDimitry Andric 260b57cec5SDimitry Andric namespace lldb_private { 270b57cec5SDimitry Andric 280b57cec5SDimitry Andric class HardcodedFormatters { 290b57cec5SDimitry Andric public: 300b57cec5SDimitry Andric template <typename FormatterType> 310b57cec5SDimitry Andric using HardcodedFormatterFinder = 320b57cec5SDimitry Andric std::function<typename FormatterType::SharedPointer( 330b57cec5SDimitry Andric lldb_private::ValueObject &, lldb::DynamicValueType, 340b57cec5SDimitry Andric FormatManager &)>; 350b57cec5SDimitry Andric 360b57cec5SDimitry Andric template <typename FormatterType> 370b57cec5SDimitry Andric using HardcodedFormatterFinders = 380b57cec5SDimitry Andric std::vector<HardcodedFormatterFinder<FormatterType>>; 390b57cec5SDimitry Andric 400b57cec5SDimitry Andric typedef HardcodedFormatterFinders<TypeFormatImpl> HardcodedFormatFinder; 410b57cec5SDimitry Andric typedef HardcodedFormatterFinders<TypeSummaryImpl> HardcodedSummaryFinder; 420b57cec5SDimitry Andric typedef HardcodedFormatterFinders<SyntheticChildren> HardcodedSyntheticFinder; 430b57cec5SDimitry Andric }; 440b57cec5SDimitry Andric 450b57cec5SDimitry Andric class FormattersMatchCandidate { 460b57cec5SDimitry Andric public: 47bdd1243dSDimitry Andric // Contains flags to indicate how this candidate was generated (e.g. if 48bdd1243dSDimitry Andric // typedefs were stripped, or pointers were skipped). These are later compared 49bdd1243dSDimitry Andric // to flags in formatters to confirm a string match. 50bdd1243dSDimitry Andric struct Flags { 51bdd1243dSDimitry Andric bool stripped_pointer = false; 52bdd1243dSDimitry Andric bool stripped_reference = false; 53bdd1243dSDimitry Andric bool stripped_typedef = false; 54bdd1243dSDimitry Andric 55bdd1243dSDimitry Andric // Returns a copy of this with the "stripped pointer" flag set. WithStrippedPointerFlags56bdd1243dSDimitry Andric Flags WithStrippedPointer() { 57bdd1243dSDimitry Andric Flags result(*this); 58bdd1243dSDimitry Andric result.stripped_pointer = true; 59bdd1243dSDimitry Andric return result; 60bdd1243dSDimitry Andric } 61bdd1243dSDimitry Andric 62bdd1243dSDimitry Andric // Returns a copy of this with the "stripped reference" flag set. WithStrippedReferenceFlags63bdd1243dSDimitry Andric Flags WithStrippedReference() { 64bdd1243dSDimitry Andric Flags result(*this); 65bdd1243dSDimitry Andric result.stripped_reference = true; 66bdd1243dSDimitry Andric return result; 67bdd1243dSDimitry Andric } 68bdd1243dSDimitry Andric 69bdd1243dSDimitry Andric // Returns a copy of this with the "stripped typedef" flag set. WithStrippedTypedefFlags70bdd1243dSDimitry Andric Flags WithStrippedTypedef() { 71bdd1243dSDimitry Andric Flags result(*this); 72bdd1243dSDimitry Andric result.stripped_typedef = true; 73bdd1243dSDimitry Andric return result; 74bdd1243dSDimitry Andric } 75bdd1243dSDimitry Andric }; 76bdd1243dSDimitry Andric FormattersMatchCandidate(ConstString name,ScriptInterpreter * script_interpreter,TypeImpl type,Flags flags)77bdd1243dSDimitry Andric FormattersMatchCandidate(ConstString name, 78bdd1243dSDimitry Andric ScriptInterpreter *script_interpreter, TypeImpl type, 79bdd1243dSDimitry Andric Flags flags) 80bdd1243dSDimitry Andric : m_type_name(name), m_script_interpreter(script_interpreter), 81bdd1243dSDimitry Andric m_type(type), m_flags(flags) {} 820b57cec5SDimitry Andric 830b57cec5SDimitry Andric ~FormattersMatchCandidate() = default; 840b57cec5SDimitry Andric GetTypeName()850b57cec5SDimitry Andric ConstString GetTypeName() const { return m_type_name; } 860b57cec5SDimitry Andric GetType()87bdd1243dSDimitry Andric TypeImpl GetType() const { return m_type; } 880b57cec5SDimitry Andric GetScriptInterpreter()89bdd1243dSDimitry Andric ScriptInterpreter *GetScriptInterpreter() const { 90bdd1243dSDimitry Andric return m_script_interpreter; 91bdd1243dSDimitry Andric } 920b57cec5SDimitry Andric DidStripPointer()93bdd1243dSDimitry Andric bool DidStripPointer() const { return m_flags.stripped_pointer; } 94bdd1243dSDimitry Andric DidStripReference()95bdd1243dSDimitry Andric bool DidStripReference() const { return m_flags.stripped_reference; } 96bdd1243dSDimitry Andric DidStripTypedef()97bdd1243dSDimitry Andric bool DidStripTypedef() const { return m_flags.stripped_typedef; } 980b57cec5SDimitry Andric 990b57cec5SDimitry Andric template <class Formatter> IsMatch(const std::shared_ptr<Formatter> & formatter_sp)1000b57cec5SDimitry Andric bool IsMatch(const std::shared_ptr<Formatter> &formatter_sp) const { 1010b57cec5SDimitry Andric if (!formatter_sp) 1020b57cec5SDimitry Andric return false; 1030b57cec5SDimitry Andric if (formatter_sp->Cascades() == false && DidStripTypedef()) 1040b57cec5SDimitry Andric return false; 1050b57cec5SDimitry Andric if (formatter_sp->SkipsPointers() && DidStripPointer()) 1060b57cec5SDimitry Andric return false; 1070b57cec5SDimitry Andric if (formatter_sp->SkipsReferences() && DidStripReference()) 1080b57cec5SDimitry Andric return false; 1090b57cec5SDimitry Andric return true; 1100b57cec5SDimitry Andric } 1110b57cec5SDimitry Andric 1120b57cec5SDimitry Andric private: 1130b57cec5SDimitry Andric ConstString m_type_name; 114bdd1243dSDimitry Andric // If a formatter provides a matching callback function, we need the script 115bdd1243dSDimitry Andric // interpreter and the type object (as an argument to the callback). 116bdd1243dSDimitry Andric ScriptInterpreter *m_script_interpreter; 117bdd1243dSDimitry Andric TypeImpl m_type; 118bdd1243dSDimitry Andric Flags m_flags; 1190b57cec5SDimitry Andric }; 1200b57cec5SDimitry Andric 1210b57cec5SDimitry Andric typedef std::vector<FormattersMatchCandidate> FormattersMatchVector; 1220b57cec5SDimitry Andric typedef std::vector<lldb::LanguageType> CandidateLanguagesVector; 1230b57cec5SDimitry Andric 1240b57cec5SDimitry Andric class FormattersMatchData { 1250b57cec5SDimitry Andric public: 1260b57cec5SDimitry Andric FormattersMatchData(ValueObject &, lldb::DynamicValueType); 1270b57cec5SDimitry Andric 1280b57cec5SDimitry Andric FormattersMatchVector GetMatchesVector(); 1290b57cec5SDimitry Andric 1300b57cec5SDimitry Andric ConstString GetTypeForCache(); 1310b57cec5SDimitry Andric 1320b57cec5SDimitry Andric CandidateLanguagesVector GetCandidateLanguages(); 1330b57cec5SDimitry Andric 1340b57cec5SDimitry Andric ValueObject &GetValueObject(); 1350b57cec5SDimitry Andric 1360b57cec5SDimitry Andric lldb::DynamicValueType GetDynamicValueType(); 1370b57cec5SDimitry Andric 1380b57cec5SDimitry Andric private: 1390b57cec5SDimitry Andric ValueObject &m_valobj; 1400b57cec5SDimitry Andric lldb::DynamicValueType m_dynamic_value_type; 1410b57cec5SDimitry Andric std::pair<FormattersMatchVector, bool> m_formatters_match_vector; 1420b57cec5SDimitry Andric ConstString m_type_for_cache; 1430b57cec5SDimitry Andric CandidateLanguagesVector m_candidate_languages; 1440b57cec5SDimitry Andric }; 1450b57cec5SDimitry Andric 1460b57cec5SDimitry Andric class TypeNameSpecifierImpl { 1470b57cec5SDimitry Andric public: 14881ad6265SDimitry Andric TypeNameSpecifierImpl() = default; 1490b57cec5SDimitry Andric TypeNameSpecifierImpl(llvm::StringRef name,lldb::FormatterMatchType match_type)150bdd1243dSDimitry Andric TypeNameSpecifierImpl(llvm::StringRef name, 151bdd1243dSDimitry Andric lldb::FormatterMatchType match_type) 152bdd1243dSDimitry Andric : m_match_type(match_type) { 1535ffd83dbSDimitry Andric m_type.m_type_name = std::string(name); 1540b57cec5SDimitry Andric } 1550b57cec5SDimitry Andric 156bdd1243dSDimitry Andric // if constructing with a given type, we consider that a case of exact match. TypeNameSpecifierImpl(lldb::TypeSP type)157bdd1243dSDimitry Andric TypeNameSpecifierImpl(lldb::TypeSP type) 158bdd1243dSDimitry Andric : m_match_type(lldb::eFormatterMatchExact) { 1590b57cec5SDimitry Andric if (type) { 1605ffd83dbSDimitry Andric m_type.m_type_name = std::string(type->GetName().GetStringRef()); 1610b57cec5SDimitry Andric m_type.m_compiler_type = type->GetForwardCompilerType(); 1620b57cec5SDimitry Andric } 1630b57cec5SDimitry Andric } 1640b57cec5SDimitry Andric TypeNameSpecifierImpl(CompilerType type)165bdd1243dSDimitry Andric TypeNameSpecifierImpl(CompilerType type) 166bdd1243dSDimitry Andric : m_match_type(lldb::eFormatterMatchExact) { 1670b57cec5SDimitry Andric if (type.IsValid()) { 1685ffd83dbSDimitry Andric m_type.m_type_name.assign(type.GetTypeName().GetCString()); 1690b57cec5SDimitry Andric m_type.m_compiler_type = type; 1700b57cec5SDimitry Andric } 1710b57cec5SDimitry Andric } 1720b57cec5SDimitry Andric GetName()1730b57cec5SDimitry Andric const char *GetName() { 1740b57cec5SDimitry Andric if (m_type.m_type_name.size()) 1750b57cec5SDimitry Andric return m_type.m_type_name.c_str(); 1760b57cec5SDimitry Andric return nullptr; 1770b57cec5SDimitry Andric } 1780b57cec5SDimitry Andric GetCompilerType()1790b57cec5SDimitry Andric CompilerType GetCompilerType() { 1800b57cec5SDimitry Andric if (m_type.m_compiler_type.IsValid()) 1810b57cec5SDimitry Andric return m_type.m_compiler_type; 1820b57cec5SDimitry Andric return CompilerType(); 1830b57cec5SDimitry Andric } 1840b57cec5SDimitry Andric GetMatchType()185bdd1243dSDimitry Andric lldb::FormatterMatchType GetMatchType() { return m_match_type; } 186bdd1243dSDimitry Andric IsRegex()187bdd1243dSDimitry Andric bool IsRegex() { return m_match_type == lldb::eFormatterMatchRegex; } 1880b57cec5SDimitry Andric 1890b57cec5SDimitry Andric private: 190bdd1243dSDimitry Andric lldb::FormatterMatchType m_match_type = lldb::eFormatterMatchExact; 1910b57cec5SDimitry Andric // TODO: Replace this with TypeAndOrName. 1920b57cec5SDimitry Andric struct TypeOrName { 1930b57cec5SDimitry Andric std::string m_type_name; 1940b57cec5SDimitry Andric CompilerType m_compiler_type; 1950b57cec5SDimitry Andric }; 1960b57cec5SDimitry Andric TypeOrName m_type; 1970b57cec5SDimitry Andric 1985ffd83dbSDimitry Andric TypeNameSpecifierImpl(const TypeNameSpecifierImpl &) = delete; 1995ffd83dbSDimitry Andric const TypeNameSpecifierImpl & 2005ffd83dbSDimitry Andric operator=(const TypeNameSpecifierImpl &) = delete; 2010b57cec5SDimitry Andric }; 2020b57cec5SDimitry Andric 2030b57cec5SDimitry Andric } // namespace lldb_private 2040b57cec5SDimitry Andric 2055ffd83dbSDimitry Andric #endif // LLDB_DATAFORMATTERS_FORMATCLASSES_H 206