| //===-- TypeSummary.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_TypeSummary_h_ |
| #define lldb_TypeSummary_h_ |
| |
| // C Includes |
| #include <stdint.h> |
| |
| // C++ Includes |
| #include <functional> |
| #include <memory> |
| #include <string> |
| |
| // Other libraries and framework includes |
| // Project includes |
| #include "lldb/lldb-enumerations.h" |
| #include "lldb/lldb-public.h" |
| |
| #include "lldb/Core/FormatEntity.h" |
| #include "lldb/Utility/Status.h" |
| #include "lldb/Utility/StructuredData.h" |
| |
| namespace lldb_private { |
| class TypeSummaryOptions { |
| public: |
| TypeSummaryOptions(); |
| TypeSummaryOptions(const TypeSummaryOptions &rhs); |
| |
| ~TypeSummaryOptions() = default; |
| |
| TypeSummaryOptions &operator=(const TypeSummaryOptions &rhs); |
| |
| lldb::LanguageType GetLanguage() const; |
| |
| lldb::TypeSummaryCapping GetCapping() const; |
| |
| TypeSummaryOptions &SetLanguage(lldb::LanguageType); |
| |
| TypeSummaryOptions &SetCapping(lldb::TypeSummaryCapping); |
| |
| private: |
| lldb::LanguageType m_lang; |
| lldb::TypeSummaryCapping m_capping; |
| }; |
| |
| class TypeSummaryImpl { |
| public: |
| enum class Kind { eSummaryString, eScript, eCallback, eInternal }; |
| |
| virtual ~TypeSummaryImpl() = default; |
| |
| Kind GetKind() const { return m_kind; } |
| |
| class Flags { |
| public: |
| Flags() : m_flags(lldb::eTypeOptionCascade) {} |
| |
| Flags(const Flags &other) : m_flags(other.m_flags) {} |
| |
| Flags(uint32_t value) : m_flags(value) {} |
| |
| Flags &operator=(const Flags &rhs) { |
| if (&rhs != this) |
| m_flags = rhs.m_flags; |
| |
| return *this; |
| } |
| |
| Flags &operator=(const uint32_t &rhs) { |
| m_flags = rhs; |
| return *this; |
| } |
| |
| Flags &Clear() { |
| m_flags = 0; |
| return *this; |
| } |
| |
| bool GetCascades() const { |
| return (m_flags & lldb::eTypeOptionCascade) == lldb::eTypeOptionCascade; |
| } |
| |
| Flags &SetCascades(bool value = true) { |
| if (value) |
| m_flags |= lldb::eTypeOptionCascade; |
| else |
| m_flags &= ~lldb::eTypeOptionCascade; |
| return *this; |
| } |
| |
| bool GetSkipPointers() const { |
| return (m_flags & lldb::eTypeOptionSkipPointers) == |
| lldb::eTypeOptionSkipPointers; |
| } |
| |
| Flags &SetSkipPointers(bool value = true) { |
| if (value) |
| m_flags |= lldb::eTypeOptionSkipPointers; |
| else |
| m_flags &= ~lldb::eTypeOptionSkipPointers; |
| return *this; |
| } |
| |
| bool GetSkipReferences() const { |
| return (m_flags & lldb::eTypeOptionSkipReferences) == |
| lldb::eTypeOptionSkipReferences; |
| } |
| |
| Flags &SetSkipReferences(bool value = true) { |
| if (value) |
| m_flags |= lldb::eTypeOptionSkipReferences; |
| else |
| m_flags &= ~lldb::eTypeOptionSkipReferences; |
| return *this; |
| } |
| |
| bool GetDontShowChildren() const { |
| return (m_flags & lldb::eTypeOptionHideChildren) == |
| lldb::eTypeOptionHideChildren; |
| } |
| |
| Flags &SetDontShowChildren(bool value = true) { |
| if (value) |
| m_flags |= lldb::eTypeOptionHideChildren; |
| else |
| m_flags &= ~lldb::eTypeOptionHideChildren; |
| return *this; |
| } |
| |
| bool GetHideEmptyAggregates() const { |
| return (m_flags & lldb::eTypeOptionHideEmptyAggregates) == |
| lldb::eTypeOptionHideEmptyAggregates; |
| } |
| |
| Flags &SetHideEmptyAggregates(bool value = true) { |
| if (value) |
| m_flags |= lldb::eTypeOptionHideEmptyAggregates; |
| else |
| m_flags &= ~lldb::eTypeOptionHideEmptyAggregates; |
| return *this; |
| } |
| |
| bool GetDontShowValue() const { |
| return (m_flags & lldb::eTypeOptionHideValue) == |
| lldb::eTypeOptionHideValue; |
| } |
| |
| Flags &SetDontShowValue(bool value = true) { |
| if (value) |
| m_flags |= lldb::eTypeOptionHideValue; |
| else |
| m_flags &= ~lldb::eTypeOptionHideValue; |
| return *this; |
| } |
| |
| bool GetShowMembersOneLiner() const { |
| return (m_flags & lldb::eTypeOptionShowOneLiner) == |
| lldb::eTypeOptionShowOneLiner; |
| } |
| |
| Flags &SetShowMembersOneLiner(bool value = true) { |
| if (value) |
| m_flags |= lldb::eTypeOptionShowOneLiner; |
| else |
| m_flags &= ~lldb::eTypeOptionShowOneLiner; |
| return *this; |
| } |
| |
| bool GetHideItemNames() const { |
| return (m_flags & lldb::eTypeOptionHideNames) == |
| lldb::eTypeOptionHideNames; |
| } |
| |
| Flags &SetHideItemNames(bool value = true) { |
| if (value) |
| m_flags |= lldb::eTypeOptionHideNames; |
| else |
| m_flags &= ~lldb::eTypeOptionHideNames; |
| return *this; |
| } |
| |
| bool GetNonCacheable() const { |
| return (m_flags & lldb::eTypeOptionNonCacheable) == |
| lldb::eTypeOptionNonCacheable; |
| } |
| |
| Flags &SetNonCacheable(bool value = true) { |
| if (value) |
| m_flags |= lldb::eTypeOptionNonCacheable; |
| else |
| m_flags &= ~lldb::eTypeOptionNonCacheable; |
| return *this; |
| } |
| |
| uint32_t GetValue() { return m_flags; } |
| |
| void SetValue(uint32_t value) { m_flags = value; } |
| |
| private: |
| uint32_t m_flags; |
| }; |
| |
| bool Cascades() const { return m_flags.GetCascades(); } |
| |
| bool SkipsPointers() const { return m_flags.GetSkipPointers(); } |
| |
| bool SkipsReferences() const { return m_flags.GetSkipReferences(); } |
| |
| bool NonCacheable() const { return m_flags.GetNonCacheable(); } |
| |
| virtual bool DoesPrintChildren(ValueObject *valobj) const { |
| return !m_flags.GetDontShowChildren(); |
| } |
| |
| virtual bool DoesPrintEmptyAggregates() const { |
| return !m_flags.GetHideEmptyAggregates(); |
| } |
| |
| virtual bool DoesPrintValue(ValueObject *valobj) const { |
| return !m_flags.GetDontShowValue(); |
| } |
| |
| bool IsOneLiner() const { return m_flags.GetShowMembersOneLiner(); } |
| |
| virtual bool HideNames(ValueObject *valobj) const { |
| return m_flags.GetHideItemNames(); |
| } |
| |
| void SetCascades(bool value) { m_flags.SetCascades(value); } |
| |
| void SetSkipsPointers(bool value) { m_flags.SetSkipPointers(value); } |
| |
| void SetSkipsReferences(bool value) { m_flags.SetSkipReferences(value); } |
| |
| virtual void SetDoesPrintChildren(bool value) { |
| m_flags.SetDontShowChildren(!value); |
| } |
| |
| virtual void SetDoesPrintValue(bool value) { |
| m_flags.SetDontShowValue(!value); |
| } |
| |
| void SetIsOneLiner(bool value) { m_flags.SetShowMembersOneLiner(value); } |
| |
| virtual void SetHideNames(bool value) { m_flags.SetHideItemNames(value); } |
| |
| virtual void SetNonCacheable(bool value) { m_flags.SetNonCacheable(value); } |
| |
| uint32_t GetOptions() { return m_flags.GetValue(); } |
| |
| void SetOptions(uint32_t value) { m_flags.SetValue(value); } |
| |
| // we are using a ValueObject* instead of a ValueObjectSP because we do not |
| // need to hold on to this for extended periods of time and we trust the |
| // ValueObject to stay around for as long as it is required for us to |
| // generate its summary |
| virtual bool FormatObject(ValueObject *valobj, std::string &dest, |
| const TypeSummaryOptions &options) = 0; |
| |
| virtual std::string GetDescription() = 0; |
| |
| uint32_t &GetRevision() { return m_my_revision; } |
| |
| typedef std::shared_ptr<TypeSummaryImpl> SharedPointer; |
| |
| protected: |
| uint32_t m_my_revision; |
| Flags m_flags; |
| |
| TypeSummaryImpl(Kind kind, const TypeSummaryImpl::Flags &flags); |
| |
| private: |
| Kind m_kind; |
| DISALLOW_COPY_AND_ASSIGN(TypeSummaryImpl); |
| }; |
| |
| // simple string-based summaries, using ${var to show data |
| struct StringSummaryFormat : public TypeSummaryImpl { |
| std::string m_format_str; |
| FormatEntity::Entry m_format; |
| Status m_error; |
| |
| StringSummaryFormat(const TypeSummaryImpl::Flags &flags, const char *f); |
| |
| ~StringSummaryFormat() override = default; |
| |
| const char *GetSummaryString() const { return m_format_str.c_str(); } |
| |
| void SetSummaryString(const char *f); |
| |
| bool FormatObject(ValueObject *valobj, std::string &dest, |
| const TypeSummaryOptions &options) override; |
| |
| std::string GetDescription() override; |
| |
| static bool classof(const TypeSummaryImpl *S) { |
| return S->GetKind() == Kind::eSummaryString; |
| } |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(StringSummaryFormat); |
| }; |
| |
| // summaries implemented via a C++ function |
| struct CXXFunctionSummaryFormat : public TypeSummaryImpl { |
| // we should convert these to SBValue and SBStream if we ever cross the |
| // boundary towards the external world |
| typedef std::function<bool(ValueObject &, Stream &, |
| const TypeSummaryOptions &)> |
| Callback; |
| |
| Callback m_impl; |
| std::string m_description; |
| |
| CXXFunctionSummaryFormat(const TypeSummaryImpl::Flags &flags, Callback impl, |
| const char *description); |
| |
| ~CXXFunctionSummaryFormat() override = default; |
| |
| Callback GetBackendFunction() const { return m_impl; } |
| |
| const char *GetTextualInfo() const { return m_description.c_str(); } |
| |
| void SetBackendFunction(Callback cb_func) { m_impl = cb_func; } |
| |
| void SetTextualInfo(const char *descr) { |
| if (descr) |
| m_description.assign(descr); |
| else |
| m_description.clear(); |
| } |
| |
| bool FormatObject(ValueObject *valobj, std::string &dest, |
| const TypeSummaryOptions &options) override; |
| |
| std::string GetDescription() override; |
| |
| static bool classof(const TypeSummaryImpl *S) { |
| return S->GetKind() == Kind::eCallback; |
| } |
| |
| typedef std::shared_ptr<CXXFunctionSummaryFormat> SharedPointer; |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(CXXFunctionSummaryFormat); |
| }; |
| |
| // Python-based summaries, running script code to show data |
| struct ScriptSummaryFormat : public TypeSummaryImpl { |
| std::string m_function_name; |
| std::string m_python_script; |
| StructuredData::ObjectSP m_script_function_sp; |
| |
| ScriptSummaryFormat(const TypeSummaryImpl::Flags &flags, |
| const char *function_name, |
| const char *python_script = nullptr); |
| |
| ~ScriptSummaryFormat() override = default; |
| |
| const char *GetFunctionName() const { return m_function_name.c_str(); } |
| |
| const char *GetPythonScript() const { return m_python_script.c_str(); } |
| |
| void SetFunctionName(const char *function_name) { |
| if (function_name) |
| m_function_name.assign(function_name); |
| else |
| m_function_name.clear(); |
| m_python_script.clear(); |
| } |
| |
| void SetPythonScript(const char *script) { |
| if (script) |
| m_python_script.assign(script); |
| else |
| m_python_script.clear(); |
| } |
| |
| bool FormatObject(ValueObject *valobj, std::string &dest, |
| const TypeSummaryOptions &options) override; |
| |
| std::string GetDescription() override; |
| |
| static bool classof(const TypeSummaryImpl *S) { |
| return S->GetKind() == Kind::eScript; |
| } |
| |
| typedef std::shared_ptr<ScriptSummaryFormat> SharedPointer; |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(ScriptSummaryFormat); |
| }; |
| } // namespace lldb_private |
| |
| #endif // lldb_TypeSummary_h_ |