//===-- FormatClasses.h -----------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #ifndef LLDB_DATAFORMATTERS_FORMATCLASSES_H #define LLDB_DATAFORMATTERS_FORMATCLASSES_H #include #include #include #include #include "lldb/DataFormatters/TypeFormat.h" #include "lldb/DataFormatters/TypeSummary.h" #include "lldb/DataFormatters/TypeSynthetic.h" #include "lldb/Interpreter/ScriptInterpreter.h" #include "lldb/Symbol/CompilerType.h" #include "lldb/Symbol/Type.h" #include "lldb/lldb-enumerations.h" #include "lldb/lldb-public.h" namespace lldb_private { class HardcodedFormatters { public: template using HardcodedFormatterFinder = std::function; template using HardcodedFormatterFinders = std::vector>; typedef HardcodedFormatterFinders HardcodedFormatFinder; typedef HardcodedFormatterFinders HardcodedSummaryFinder; typedef HardcodedFormatterFinders HardcodedSyntheticFinder; }; class FormattersMatchCandidate { public: // Contains flags to indicate how this candidate was generated (e.g. if // typedefs were stripped, or pointers were skipped). These are later compared // to flags in formatters to confirm a string match. struct Flags { bool stripped_pointer = false; bool stripped_reference = false; bool stripped_typedef = false; // Returns a copy of this with the "stripped pointer" flag set. Flags WithStrippedPointer() { Flags result(*this); result.stripped_pointer = true; return result; } // Returns a copy of this with the "stripped reference" flag set. Flags WithStrippedReference() { Flags result(*this); result.stripped_reference = true; return result; } // Returns a copy of this with the "stripped typedef" flag set. Flags WithStrippedTypedef() { Flags result(*this); result.stripped_typedef = true; return result; } }; FormattersMatchCandidate(ConstString name, ScriptInterpreter *script_interpreter, TypeImpl type, Flags flags) : m_type_name(name), m_script_interpreter(script_interpreter), m_type(type), m_flags(flags) {} ~FormattersMatchCandidate() = default; ConstString GetTypeName() const { return m_type_name; } TypeImpl GetType() const { return m_type; } ScriptInterpreter *GetScriptInterpreter() const { return m_script_interpreter; } bool DidStripPointer() const { return m_flags.stripped_pointer; } bool DidStripReference() const { return m_flags.stripped_reference; } bool DidStripTypedef() const { return m_flags.stripped_typedef; } template bool IsMatch(const std::shared_ptr &formatter_sp) const { if (!formatter_sp) return false; if (formatter_sp->Cascades() == false && DidStripTypedef()) return false; if (formatter_sp->SkipsPointers() && DidStripPointer()) return false; if (formatter_sp->SkipsReferences() && DidStripReference()) return false; return true; } private: ConstString m_type_name; // If a formatter provides a matching callback function, we need the script // interpreter and the type object (as an argument to the callback). ScriptInterpreter *m_script_interpreter; TypeImpl m_type; Flags m_flags; }; typedef std::vector FormattersMatchVector; typedef std::vector CandidateLanguagesVector; class FormattersMatchData { public: FormattersMatchData(ValueObject &, lldb::DynamicValueType); FormattersMatchVector GetMatchesVector(); ConstString GetTypeForCache(); CandidateLanguagesVector GetCandidateLanguages(); ValueObject &GetValueObject(); lldb::DynamicValueType GetDynamicValueType(); private: ValueObject &m_valobj; lldb::DynamicValueType m_dynamic_value_type; std::pair m_formatters_match_vector; ConstString m_type_for_cache; CandidateLanguagesVector m_candidate_languages; }; class TypeNameSpecifierImpl { public: TypeNameSpecifierImpl() = default; TypeNameSpecifierImpl(llvm::StringRef name, lldb::FormatterMatchType match_type) : m_match_type(match_type) { m_type.m_type_name = std::string(name); } // if constructing with a given type, we consider that a case of exact match. TypeNameSpecifierImpl(lldb::TypeSP type) : m_match_type(lldb::eFormatterMatchExact) { if (type) { m_type.m_type_name = std::string(type->GetName().GetStringRef()); m_type.m_compiler_type = type->GetForwardCompilerType(); } } TypeNameSpecifierImpl(CompilerType type) : m_match_type(lldb::eFormatterMatchExact) { if (type.IsValid()) { m_type.m_type_name.assign(type.GetTypeName().GetCString()); m_type.m_compiler_type = type; } } const char *GetName() { if (m_type.m_type_name.size()) return m_type.m_type_name.c_str(); return nullptr; } CompilerType GetCompilerType() { if (m_type.m_compiler_type.IsValid()) return m_type.m_compiler_type; return CompilerType(); } lldb::FormatterMatchType GetMatchType() { return m_match_type; } bool IsRegex() { return m_match_type == lldb::eFormatterMatchRegex; } private: lldb::FormatterMatchType m_match_type = lldb::eFormatterMatchExact; // TODO: Replace this with TypeAndOrName. struct TypeOrName { std::string m_type_name; CompilerType m_compiler_type; }; TypeOrName m_type; TypeNameSpecifierImpl(const TypeNameSpecifierImpl &) = delete; const TypeNameSpecifierImpl & operator=(const TypeNameSpecifierImpl &) = delete; }; } // namespace lldb_private #endif // LLDB_DATAFORMATTERS_FORMATCLASSES_H