diff options
author | Tamas Berghammer <tberghammer@google.com> | 2016-10-21 15:02:44 +0000 |
---|---|---|
committer | Tamas Berghammer <tberghammer@google.com> | 2016-10-21 15:02:44 +0000 |
commit | d161b2147bb23ebfb14375f70cef5d47eb41dfb4 (patch) | |
tree | 350f22f913f3b5c4a059b16e2ab8c2618651f2db /lldb/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp | |
parent | 7f15dba16dbf9eea02b6c8973744fb3459b159b7 (diff) | |
download | bcm5719-llvm-d161b2147bb23ebfb14375f70cef5d47eb41dfb4.tar.gz bcm5719-llvm-d161b2147bb23ebfb14375f70cef5d47eb41dfb4.zip |
Add data formatter for libstdc++ unique_ptr
Differential revision: https://reviews.llvm.org/D25734
llvm-svn: 284830
Diffstat (limited to 'lldb/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp')
-rw-r--r-- | lldb/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp | 160 |
1 files changed, 160 insertions, 0 deletions
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); +} |