diff options
Diffstat (limited to 'lldb/source/Plugins/Language')
4 files changed, 180 insertions, 0 deletions
diff --git a/lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt b/lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt index 63a1335015a..a72aee7f67d 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt +++ b/lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt @@ -12,4 +12,5 @@ add_lldb_library(lldbPluginCPlusPlusLanguage LibStdcpp.cpp LibStdcppSmartPointer.cpp LibStdcppTuple.cpp + LibStdcppUniquePointer.cpp ) diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp index f0b5fb8b4c1..e7bc78c15ad 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp @@ -803,6 +803,11 @@ static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { AddCXXSynthetic( cpp_category_sp, + lldb_private::formatters::LibStdcppUniquePtrSyntheticFrontEndCreator, + "std::unique_ptr synthetic children", + ConstString("^std::unique_ptr<.+>(( )?&)?$"), stl_synth_flags, true); + AddCXXSynthetic( + cpp_category_sp, lldb_private::formatters::LibStdcppSharedPtrSyntheticFrontEndCreator, "std::shared_ptr synthetic children", ConstString("^std::shared_ptr<.+>(( )?&)?$"), stl_synth_flags, true); @@ -818,6 +823,11 @@ static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { stl_synth_flags, true); AddCXXSummary(cpp_category_sp, + lldb_private::formatters::LibStdcppUniquePointerSummaryProvider, + "libstdc++ std::unique_ptr summary provider", + ConstString("^std::unique_ptr<.+>(( )?&)?$"), stl_summary_flags, + true); + AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibStdcppSmartPointerSummaryProvider, "libstdc++ std::shared_ptr summary provider", ConstString("^std::shared_ptr<.+>(( )?&)?$"), stl_summary_flags, diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.h b/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.h index 1c579af7f62..bcb7d8cf72d 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.h +++ b/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.h @@ -31,6 +31,10 @@ bool LibStdcppSmartPointerSummaryProvider( const TypeSummaryOptions &options); // libstdc++ std::shared_ptr<> and std::weak_ptr<> +bool LibStdcppUniquePointerSummaryProvider( + ValueObject &valobj, Stream &stream, + const TypeSummaryOptions &options); // libstdc++ std::unique_ptr<> + SyntheticChildrenFrontEnd * LibstdcppMapIteratorSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP); @@ -46,6 +50,11 @@ LibStdcppVectorIteratorSyntheticFrontEndCreator(CXXSyntheticChildren *, SyntheticChildrenFrontEnd * LibStdcppSharedPtrSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP); + +SyntheticChildrenFrontEnd * +LibStdcppUniquePtrSyntheticFrontEndCreator(CXXSyntheticChildren *, + lldb::ValueObjectSP); + } // namespace formatters } // namespace lldb_private diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp new file mode 100644 index 00000000000..03acc3bf905 --- /dev/null +++ b/lldb/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp @@ -0,0 +1,160 @@ +//===-- LibStdcppUniquePointer.cpp ------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "LibStdcpp.h" + +#include <memory> +#include <vector> + +#include "lldb/Core/ConstString.h" +#include "lldb/Core/ValueObject.h" +#include "lldb/DataFormatters/FormattersHelpers.h" +#include "lldb/DataFormatters/TypeSynthetic.h" + +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::formatters; + +namespace { + +class LibStdcppUniquePtrSyntheticFrontEnd : public SyntheticChildrenFrontEnd { +public: + explicit LibStdcppUniquePtrSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp); + + size_t CalculateNumChildren() override; + + lldb::ValueObjectSP GetChildAtIndex(size_t idx) override; + + bool Update() override; + + bool MightHaveChildren() override; + + size_t GetIndexOfChildWithName(const ConstString &name) override; + + bool GetSummary(Stream &stream, const TypeSummaryOptions &options); + +private: + ValueObjectSP m_ptr_obj; + ValueObjectSP m_obj_obj; + ValueObjectSP m_del_obj; +}; + +} // end of anonymous namespace + +LibStdcppUniquePtrSyntheticFrontEnd::LibStdcppUniquePtrSyntheticFrontEnd( + lldb::ValueObjectSP valobj_sp) + : SyntheticChildrenFrontEnd(*valobj_sp) { + Update(); +} + +bool LibStdcppUniquePtrSyntheticFrontEnd::Update() { + ValueObjectSP valobj_backend_sp = m_backend.GetSP(); + if (!valobj_backend_sp) + return false; + + ValueObjectSP valobj_sp = valobj_backend_sp->GetNonSyntheticValue(); + if (!valobj_sp) + return false; + + ValueObjectSP tuple_sp = + valobj_sp->GetChildMemberWithName(ConstString("_M_t"), true); + if (!tuple_sp) + return false; + + std::unique_ptr<SyntheticChildrenFrontEnd> tuple_frontend( + LibStdcppTupleSyntheticFrontEndCreator(nullptr, tuple_sp)); + + m_ptr_obj = tuple_frontend->GetChildAtIndex(0); + if (m_ptr_obj) + m_ptr_obj->SetName(ConstString("pointer")); + + m_del_obj = tuple_frontend->GetChildAtIndex(1); + if (m_del_obj) + m_del_obj->SetName(ConstString("deleter")); + + if (m_ptr_obj) { + Error error; + m_obj_obj = m_ptr_obj->Dereference(error); + if (error.Success()) { + m_obj_obj->SetName(ConstString("object")); + } + } + + return false; +} + +bool LibStdcppUniquePtrSyntheticFrontEnd::MightHaveChildren() { return true; } + +lldb::ValueObjectSP +LibStdcppUniquePtrSyntheticFrontEnd::GetChildAtIndex(size_t idx) { + if (idx == 0) + return m_obj_obj; + if (idx == 1) + return m_del_obj; + if (idx == 2) + return m_ptr_obj; + return lldb::ValueObjectSP(); +} + +size_t LibStdcppUniquePtrSyntheticFrontEnd::CalculateNumChildren() { + if (m_del_obj) + return 2; + if (m_ptr_obj && m_ptr_obj->GetValueAsUnsigned(0) != 0) + return 1; + return 0; +} + +size_t LibStdcppUniquePtrSyntheticFrontEnd::GetIndexOfChildWithName( + const ConstString &name) { + if (name == ConstString("obj") || name == ConstString("object")) + return 0; + if (name == ConstString("del") || name == ConstString("deleter")) + return 1; + if (name == ConstString("ptr") || name == ConstString("pointer")) + return 2; + return UINT32_MAX; +} + +bool LibStdcppUniquePtrSyntheticFrontEnd::GetSummary( + Stream &stream, const TypeSummaryOptions &options) { + if (!m_ptr_obj) + return false; + + if (m_ptr_obj->GetValueAsUnsigned(0) == 0) { + stream.Printf("nullptr"); + } else { + Error error; + bool print_pointee = false; + if (m_obj_obj) { + if (m_obj_obj->DumpPrintableRepresentation( + stream, ValueObject::eValueObjectRepresentationStyleSummary, + lldb::eFormatInvalid, + ValueObject::ePrintableRepresentationSpecialCasesDisable, + false)) { + print_pointee = true; + } + } + if (!print_pointee) + stream.Printf("ptr = 0x%" PRIx64, m_ptr_obj->GetValueAsUnsigned(0)); + } + return true; +} + +SyntheticChildrenFrontEnd * +lldb_private::formatters::LibStdcppUniquePtrSyntheticFrontEndCreator( + CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) { + return (valobj_sp ? new LibStdcppUniquePtrSyntheticFrontEnd(valobj_sp) + : nullptr); +} + +bool lldb_private::formatters::LibStdcppUniquePointerSummaryProvider( + ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) { + LibStdcppUniquePtrSyntheticFrontEnd formatter(valobj.GetSP()); + return formatter.GetSummary(stream, options); +} |