From e85fe3a4d103b55f9bde86b7afc9253a0039b40a Mon Sep 17 00:00:00 2001 From: Enrico Granata Date: Wed, 22 Oct 2014 20:34:38 +0000 Subject: [PATCH] Reorganize some of the data formatters code to simplify CXXFormattersFunction.h. Also, add a synthetic child provider for libc++'s version of std::initializer_list llvm-svn: 220421 --- .../DataFormatters/CXXFormatterFunctions.h | 137 +-------------- lldb/lldb.xcodeproj/project.pbxproj | 8 + lldb/source/DataFormatters/FormatManager.cpp | 1 + lldb/source/DataFormatters/LibCxx.cpp | 103 ------------ .../DataFormatters/LibCxxInitializerList.cpp | 145 ++++++++++++++++ lldb/source/DataFormatters/LibCxxList.cpp | 41 +++++ lldb/source/DataFormatters/LibCxxMap.cpp | 41 +++++ .../DataFormatters/LibCxxUnorderedMap.cpp | 35 ++++ lldb/source/DataFormatters/LibCxxVector.cpp | 157 ++++++++++++++++++ .../initializerlist/TestInitializerList.py | 3 + .../libcxx/initializerlist/main.cpp | 21 +++ 11 files changed, 454 insertions(+), 238 deletions(-) create mode 100644 lldb/source/DataFormatters/LibCxxInitializerList.cpp create mode 100644 lldb/source/DataFormatters/LibCxxVector.cpp create mode 100644 lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/initializerlist/TestInitializerList.py create mode 100644 lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/initializerlist/main.cpp diff --git a/lldb/include/lldb/DataFormatters/CXXFormatterFunctions.h b/lldb/include/lldb/DataFormatters/CXXFormatterFunctions.h index f8e27f3e70a2..8f3f693fdff4 100644 --- a/lldb/include/lldb/DataFormatters/CXXFormatterFunctions.h +++ b/lldb/include/lldb/DataFormatters/CXXFormatterFunctions.h @@ -667,149 +667,16 @@ namespace lldb_private { SyntheticChildrenFrontEnd* LibcxxSharedPtrSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP); - class LibcxxStdVectorSyntheticFrontEnd : public SyntheticChildrenFrontEnd - { - public: - LibcxxStdVectorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp); - - virtual size_t - CalculateNumChildren (); - - virtual lldb::ValueObjectSP - GetChildAtIndex (size_t idx); - - virtual bool - Update(); - - virtual bool - MightHaveChildren (); - - virtual size_t - GetIndexOfChildWithName (const ConstString &name); - - virtual - ~LibcxxStdVectorSyntheticFrontEnd (); - private: - ValueObject* m_start; - ValueObject* m_finish; - ClangASTType m_element_type; - uint32_t m_element_size; - std::map m_children; - }; - SyntheticChildrenFrontEnd* LibcxxStdVectorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP); - class LibcxxStdListSyntheticFrontEnd : public SyntheticChildrenFrontEnd - { - public: - LibcxxStdListSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp); - - virtual size_t - CalculateNumChildren (); - - virtual lldb::ValueObjectSP - GetChildAtIndex (size_t idx); - - virtual bool - Update(); - - virtual bool - MightHaveChildren (); - - virtual size_t - GetIndexOfChildWithName (const ConstString &name); - - virtual - ~LibcxxStdListSyntheticFrontEnd (); - private: - bool - HasLoop(size_t); - - size_t m_list_capping_size; - static const bool g_use_loop_detect = true; - size_t m_loop_detected; - lldb::addr_t m_node_address; - ValueObject* m_head; - ValueObject* m_tail; - ClangASTType m_element_type; - size_t m_count; - std::map m_children; - }; - SyntheticChildrenFrontEnd* LibcxxStdListSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP); - class LibcxxStdMapSyntheticFrontEnd : public SyntheticChildrenFrontEnd - { - public: - LibcxxStdMapSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp); - - virtual size_t - CalculateNumChildren (); - - virtual lldb::ValueObjectSP - GetChildAtIndex (size_t idx); - - virtual bool - Update(); - - virtual bool - MightHaveChildren (); - - virtual size_t - GetIndexOfChildWithName (const ConstString &name); - - virtual - ~LibcxxStdMapSyntheticFrontEnd (); - private: - bool - GetDataType(); - - void - GetValueOffset (const lldb::ValueObjectSP& node); - - ValueObject* m_tree; - ValueObject* m_root_node; - ClangASTType m_element_type; - uint32_t m_skip_size; - size_t m_count; - std::map m_children; - }; - SyntheticChildrenFrontEnd* LibcxxStdMapSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP); - class LibcxxStdUnorderedMapSyntheticFrontEnd : public SyntheticChildrenFrontEnd - { - public: - LibcxxStdUnorderedMapSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp); - - virtual size_t - CalculateNumChildren (); - - virtual lldb::ValueObjectSP - GetChildAtIndex (size_t idx); - - virtual bool - Update(); - - virtual bool - MightHaveChildren (); - - virtual size_t - GetIndexOfChildWithName (const ConstString &name); - - virtual - ~LibcxxStdUnorderedMapSyntheticFrontEnd (); - private: - - ValueObject* m_tree; - size_t m_num_elements; - ValueObject* m_next_element; - std::map m_children; - std::vector > m_elements_cache; - }; - SyntheticChildrenFrontEnd* LibcxxStdUnorderedMapSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP); + SyntheticChildrenFrontEnd* LibcxxInitializerListSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP); + } // namespace formatters } // namespace lldb_private diff --git a/lldb/lldb.xcodeproj/project.pbxproj b/lldb/lldb.xcodeproj/project.pbxproj index fdfbf783056f..689e860896df 100644 --- a/lldb/lldb.xcodeproj/project.pbxproj +++ b/lldb/lldb.xcodeproj/project.pbxproj @@ -646,6 +646,8 @@ 941BCC8014E48C4000BB969C /* SBTypeFormat.h in Headers */ = {isa = PBXBuildFile; fileRef = 9461568714E355F2003A195C /* SBTypeFormat.h */; settings = {ATTRIBUTES = (Public, ); }; }; 941BCC8114E48C4000BB969C /* SBTypeSummary.h in Headers */ = {isa = PBXBuildFile; fileRef = 9461568814E355F2003A195C /* SBTypeSummary.h */; settings = {ATTRIBUTES = (Public, ); }; }; 941BCC8214E48C4000BB969C /* SBTypeSynthetic.h in Headers */ = {isa = PBXBuildFile; fileRef = 9461568914E355F2003A195C /* SBTypeSynthetic.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 942AFF0519F84ABF007B43B4 /* LibCxxVector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 942AFF0419F84ABF007B43B4 /* LibCxxVector.cpp */; }; + 942AFF0719F84C02007B43B4 /* LibCxxInitializerList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 942AFF0619F84C02007B43B4 /* LibCxxInitializerList.cpp */; }; 94380B8219940B0A00BFE4A8 /* StringLexer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94380B8119940B0A00BFE4A8 /* StringLexer.cpp */; }; 9439FB1A19EF140C006FD6A4 /* NSIndexPath.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9439FB1919EF140C006FD6A4 /* NSIndexPath.cpp */; }; 944372DC171F6B4300E57C32 /* RegisterContextDummy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 944372DA171F6B4300E57C32 /* RegisterContextDummy.cpp */; }; @@ -1983,6 +1985,8 @@ 940B02F519DC96E700AD0F52 /* SBExecutionContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBExecutionContext.cpp; path = source/API/SBExecutionContext.cpp; sourceTree = ""; }; 940B02F719DC970900AD0F52 /* SBExecutionContext.i */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c.preprocessed; path = SBExecutionContext.i; sourceTree = ""; }; 94145430175D7FDE00284436 /* lldb-versioning.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "lldb-versioning.h"; path = "include/lldb/lldb-versioning.h"; sourceTree = ""; }; + 942AFF0419F84ABF007B43B4 /* LibCxxVector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LibCxxVector.cpp; path = source/DataFormatters/LibCxxVector.cpp; sourceTree = ""; }; + 942AFF0619F84C02007B43B4 /* LibCxxInitializerList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LibCxxInitializerList.cpp; path = source/DataFormatters/LibCxxInitializerList.cpp; sourceTree = ""; }; 94380B8019940B0300BFE4A8 /* StringLexer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = StringLexer.h; path = include/lldb/Utility/StringLexer.h; sourceTree = ""; }; 94380B8119940B0A00BFE4A8 /* StringLexer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StringLexer.cpp; path = source/Utility/StringLexer.cpp; sourceTree = ""; }; 9439FB1919EF140C006FD6A4 /* NSIndexPath.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = NSIndexPath.cpp; path = source/DataFormatters/NSIndexPath.cpp; sourceTree = ""; }; @@ -4322,9 +4326,11 @@ 94CB255A16B069770059775D /* FormatManager.cpp */, 94EE33F218643C6900CD703B /* FormattersContainer.h */, 94D0B10A16D5535900EA9C70 /* LibCxx.cpp */, + 942AFF0619F84C02007B43B4 /* LibCxxInitializerList.cpp */, 94CD704F16F8DF1C00CF1E42 /* LibCxxList.cpp */, 94CD705116F8F5BC00CF1E42 /* LibCxxMap.cpp */, 94EA27CD17DE91750070F505 /* LibCxxUnorderedMap.cpp */, + 942AFF0419F84ABF007B43B4 /* LibCxxVector.cpp */, 94D0B10B16D5535900EA9C70 /* LibStdcpp.cpp */, 94D6A0A716CEB55F00833B6E /* NSArray.cpp */, 94D6A0A816CEB55F00833B6E /* NSDictionary.cpp */, @@ -5105,6 +5111,7 @@ 3FDFED0F19B7D269009756A7 /* ThisThread.cpp in Sources */, 2689005F13353E0E00698AC0 /* ClangFunction.cpp in Sources */, 2689006013353E0E00698AC0 /* ClangExpressionDeclMap.cpp in Sources */, + 942AFF0719F84C02007B43B4 /* LibCxxInitializerList.cpp in Sources */, 2689006113353E0E00698AC0 /* ClangExpressionParser.cpp in Sources */, 2689006213353E0E00698AC0 /* ClangExpressionVariable.cpp in Sources */, 2689006313353E0E00698AC0 /* ClangPersistentVariables.cpp in Sources */, @@ -5249,6 +5256,7 @@ 26BC17AD18C7F4CB00D2196D /* RegisterContextPOSIXCore_mips64.cpp in Sources */, 268900F113353E6F00698AC0 /* RegisterContext.cpp in Sources */, 268900F213353E6F00698AC0 /* SectionLoadList.cpp in Sources */, + 942AFF0519F84ABF007B43B4 /* LibCxxVector.cpp in Sources */, 268900F313353E6F00698AC0 /* StackFrame.cpp in Sources */, 268900F413353E6F00698AC0 /* StackFrameList.cpp in Sources */, 268900F513353E6F00698AC0 /* StackID.cpp in Sources */, diff --git a/lldb/source/DataFormatters/FormatManager.cpp b/lldb/source/DataFormatters/FormatManager.cpp index e7bda545a47b..c425d0d853a3 100644 --- a/lldb/source/DataFormatters/FormatManager.cpp +++ b/lldb/source/DataFormatters/FormatManager.cpp @@ -1085,6 +1085,7 @@ FormatManager::LoadLibcxxFormatters() AddCXXSynthetic(libcxx_category_sp, lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator, "libc++ std::multiset synthetic children", ConstString("^std::__1::multiset<.+> >(( )?&)?$"), stl_synth_flags, true); AddCXXSynthetic(libcxx_category_sp, lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator, "libc++ std::multimap synthetic children", ConstString("^std::__1::multimap<.+> >(( )?&)?$"), stl_synth_flags, true); AddCXXSynthetic(libcxx_category_sp, lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEndCreator, "libc++ std::unordered containers synthetic children", ConstString("^(std::__1::)unordered_(multi)?(map|set)<.+> >$"), stl_synth_flags, true); + AddCXXSynthetic(libcxx_category_sp, lldb_private::formatters::LibcxxInitializerListSyntheticFrontEndCreator, "libc++ std::initializer_list synthetic children", ConstString("^std::initializer_list<.+>(( )?&)?$"), stl_synth_flags, true); libcxx_category_sp->GetRegexTypeSyntheticsContainer()->Add(RegularExpressionSP(new RegularExpression("^(std::__1::)deque<.+>(( )?&)?$")), SyntheticChildrenSP(new ScriptedSyntheticChildren(stl_synth_flags, diff --git a/lldb/source/DataFormatters/LibCxx.cpp b/lldb/source/DataFormatters/LibCxx.cpp index 174202661f03..c68817d680b1 100644 --- a/lldb/source/DataFormatters/LibCxx.cpp +++ b/lldb/source/DataFormatters/LibCxx.cpp @@ -450,109 +450,6 @@ lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator (CXXSyntheticC return (new LibcxxSharedPtrSyntheticFrontEnd(valobj_sp)); } -lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::LibcxxStdVectorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) : - SyntheticChildrenFrontEnd(*valobj_sp.get()), - m_start(NULL), - m_finish(NULL), - m_element_type(), - m_element_size(0), - m_children() -{ - if (valobj_sp) - Update(); -} - -size_t -lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::CalculateNumChildren () -{ - if (!m_start || !m_finish) - return 0; - uint64_t start_val = m_start->GetValueAsUnsigned(0); - uint64_t finish_val = m_finish->GetValueAsUnsigned(0); - - if (start_val == 0 || finish_val == 0) - return 0; - - if (start_val >= finish_val) - return 0; - - size_t num_children = (finish_val - start_val); - if (num_children % m_element_size) - return 0; - return num_children/m_element_size; -} - -lldb::ValueObjectSP -lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::GetChildAtIndex (size_t idx) -{ - if (!m_start || !m_finish) - return lldb::ValueObjectSP(); - - auto cached = m_children.find(idx); - if (cached != m_children.end()) - return cached->second; - - uint64_t offset = idx * m_element_size; - offset = offset + m_start->GetValueAsUnsigned(0); - StreamString name; - name.Printf("[%" PRIu64 "]", (uint64_t)idx); - ValueObjectSP child_sp = ValueObject::CreateValueObjectFromAddress(name.GetData(), offset, m_backend.GetExecutionContextRef(), m_element_type); - m_children[idx] = child_sp; - return child_sp; -} - -bool -lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::Update() -{ - m_start = m_finish = NULL; - m_children.clear(); - ValueObjectSP data_type_finder_sp(m_backend.GetChildMemberWithName(ConstString("__end_cap_"),true)); - if (!data_type_finder_sp) - return false; - data_type_finder_sp = data_type_finder_sp->GetChildMemberWithName(ConstString("__first_"),true); - if (!data_type_finder_sp) - return false; - m_element_type = data_type_finder_sp->GetClangType().GetPointeeType(); - m_element_size = m_element_type.GetByteSize(); - - if (m_element_size > 0) - { - // store raw pointers or end up with a circular dependency - m_start = m_backend.GetChildMemberWithName(ConstString("__begin_"),true).get(); - m_finish = m_backend.GetChildMemberWithName(ConstString("__end_"),true).get(); - } - return false; -} - -bool -lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::MightHaveChildren () -{ - return true; -} - -size_t -lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name) -{ - if (!m_start || !m_finish) - return UINT32_MAX; - return ExtractIndexFromString(name.GetCString()); -} - -lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::~LibcxxStdVectorSyntheticFrontEnd () -{ - // these need to stay around because they are child objects who will follow their parent's life cycle - // delete m_start; - // delete m_finish; -} - -SyntheticChildrenFrontEnd* -lldb_private::formatters::LibcxxStdVectorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp) -{ - if (!valobj_sp) - return NULL; - return (new LibcxxStdVectorSyntheticFrontEnd(valobj_sp)); -} - bool lldb_private::formatters::LibcxxContainerSummaryProvider (ValueObject& valobj, Stream& stream) { diff --git a/lldb/source/DataFormatters/LibCxxInitializerList.cpp b/lldb/source/DataFormatters/LibCxxInitializerList.cpp new file mode 100644 index 000000000000..e0bed386bf0a --- /dev/null +++ b/lldb/source/DataFormatters/LibCxxInitializerList.cpp @@ -0,0 +1,145 @@ +//===-- LibCxxInitializerList.cpp ----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/lldb-python.h" + +#include "lldb/DataFormatters/CXXFormatterFunctions.h" + +#include "lldb/Core/ConstString.h" +#include "lldb/Core/ValueObject.h" + +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::formatters; + +namespace lldb_private { + namespace formatters { + class LibcxxInitializerListSyntheticFrontEnd : public SyntheticChildrenFrontEnd + { + public: + LibcxxInitializerListSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp); + + virtual size_t + CalculateNumChildren (); + + virtual lldb::ValueObjectSP + GetChildAtIndex (size_t idx); + + virtual bool + Update(); + + virtual bool + MightHaveChildren (); + + virtual size_t + GetIndexOfChildWithName (const ConstString &name); + + virtual + ~LibcxxInitializerListSyntheticFrontEnd (); + private: + ValueObject* m_start; + ClangASTType m_element_type; + uint32_t m_element_size; + size_t m_num_elements; + std::map m_children; + }; + } +} + +lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd::LibcxxInitializerListSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) : +SyntheticChildrenFrontEnd(*valobj_sp.get()), +m_start(NULL), +m_element_type(), +m_element_size(0), +m_num_elements(0), +m_children() +{ + if (valobj_sp) + Update(); +} + +size_t +lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd::CalculateNumChildren () +{ + static ConstString g___size_("__size_"); + m_num_elements = 0; + ValueObjectSP size_sp(m_backend.GetChildMemberWithName(g___size_, true)); + if (size_sp) + m_num_elements = size_sp->GetValueAsUnsigned(0); + return m_num_elements; +} + +lldb::ValueObjectSP +lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd::GetChildAtIndex (size_t idx) +{ + if (!m_start) + return lldb::ValueObjectSP(); + + auto cached = m_children.find(idx); + if (cached != m_children.end()) + return cached->second; + + uint64_t offset = idx * m_element_size; + offset = offset + m_start->GetValueAsUnsigned(0); + StreamString name; + name.Printf("[%" PRIu64 "]", (uint64_t)idx); + ValueObjectSP child_sp = ValueObject::CreateValueObjectFromAddress(name.GetData(), offset, m_backend.GetExecutionContextRef(), m_element_type); + m_children[idx] = child_sp; + return child_sp; +} + +bool +lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd::Update() +{ + static ConstString g___begin_("__begin_"); + + m_start = nullptr; + m_num_elements = 0; + m_children.clear(); + lldb::TemplateArgumentKind kind; + m_element_type = m_backend.GetClangType().GetTemplateArgument(0, kind); + if (kind != lldb::eTemplateArgumentKindType || false == m_element_type.IsValid()) + return false; + + m_element_size = m_element_type.GetByteSize(); + + if (m_element_size > 0) + m_start = m_backend.GetChildMemberWithName(g___begin_,true).get(); // store raw pointers or end up with a circular dependency + + return false; +} + +bool +lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd::MightHaveChildren () +{ + return true; +} + +size_t +lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name) +{ + if (!m_start) + return UINT32_MAX; + return ExtractIndexFromString(name.GetCString()); +} + +lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd::~LibcxxInitializerListSyntheticFrontEnd () +{ + // this needs to stay around because it's a child object who will follow its parent's life cycle + // delete m_start; +} + +lldb_private::SyntheticChildrenFrontEnd* +lldb_private::formatters::LibcxxInitializerListSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp) +{ + if (!valobj_sp) + return NULL; + return (new LibcxxInitializerListSyntheticFrontEnd(valobj_sp)); +} + diff --git a/lldb/source/DataFormatters/LibCxxList.cpp b/lldb/source/DataFormatters/LibCxxList.cpp index 5c930564da13..937279b37cac 100644 --- a/lldb/source/DataFormatters/LibCxxList.cpp +++ b/lldb/source/DataFormatters/LibCxxList.cpp @@ -25,6 +25,47 @@ using namespace lldb; using namespace lldb_private; using namespace lldb_private::formatters; +namespace lldb_private { + namespace formatters { + class LibcxxStdListSyntheticFrontEnd : public SyntheticChildrenFrontEnd + { + public: + LibcxxStdListSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp); + + virtual size_t + CalculateNumChildren (); + + virtual lldb::ValueObjectSP + GetChildAtIndex (size_t idx); + + virtual bool + Update(); + + virtual bool + MightHaveChildren (); + + virtual size_t + GetIndexOfChildWithName (const ConstString &name); + + virtual + ~LibcxxStdListSyntheticFrontEnd (); + private: + bool + HasLoop(size_t); + + size_t m_list_capping_size; + static const bool g_use_loop_detect = true; + size_t m_loop_detected; + lldb::addr_t m_node_address; + ValueObject* m_head; + ValueObject* m_tail; + ClangASTType m_element_type; + size_t m_count; + std::map m_children; + }; + } +} + class ListEntry { public: diff --git a/lldb/source/DataFormatters/LibCxxMap.cpp b/lldb/source/DataFormatters/LibCxxMap.cpp index 9a231ad6d11f..1dc8f54cdd68 100644 --- a/lldb/source/DataFormatters/LibCxxMap.cpp +++ b/lldb/source/DataFormatters/LibCxxMap.cpp @@ -25,6 +25,47 @@ using namespace lldb; using namespace lldb_private; using namespace lldb_private::formatters; +namespace lldb_private { + namespace formatters { + class LibcxxStdMapSyntheticFrontEnd : public SyntheticChildrenFrontEnd + { + public: + LibcxxStdMapSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp); + + virtual size_t + CalculateNumChildren (); + + virtual lldb::ValueObjectSP + GetChildAtIndex (size_t idx); + + virtual bool + Update(); + + virtual bool + MightHaveChildren (); + + virtual size_t + GetIndexOfChildWithName (const ConstString &name); + + virtual + ~LibcxxStdMapSyntheticFrontEnd (); + private: + bool + GetDataType(); + + void + GetValueOffset (const lldb::ValueObjectSP& node); + + ValueObject* m_tree; + ValueObject* m_root_node; + ClangASTType m_element_type; + uint32_t m_skip_size; + size_t m_count; + std::map m_children; + }; + } +} + class MapEntry { public: diff --git a/lldb/source/DataFormatters/LibCxxUnorderedMap.cpp b/lldb/source/DataFormatters/LibCxxUnorderedMap.cpp index bf68f20955b5..da2a88966f5e 100644 --- a/lldb/source/DataFormatters/LibCxxUnorderedMap.cpp +++ b/lldb/source/DataFormatters/LibCxxUnorderedMap.cpp @@ -25,6 +25,41 @@ using namespace lldb; using namespace lldb_private; using namespace lldb_private::formatters; +namespace lldb_private { + namespace formatters { + class LibcxxStdUnorderedMapSyntheticFrontEnd : public SyntheticChildrenFrontEnd + { + public: + LibcxxStdUnorderedMapSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp); + + virtual size_t + CalculateNumChildren (); + + virtual lldb::ValueObjectSP + GetChildAtIndex (size_t idx); + + virtual bool + Update(); + + virtual bool + MightHaveChildren (); + + virtual size_t + GetIndexOfChildWithName (const ConstString &name); + + virtual + ~LibcxxStdUnorderedMapSyntheticFrontEnd (); + private: + + ValueObject* m_tree; + size_t m_num_elements; + ValueObject* m_next_element; + std::map m_children; + std::vector > m_elements_cache; + }; + } +} + lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::LibcxxStdUnorderedMapSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) : SyntheticChildrenFrontEnd(*valobj_sp.get()), m_tree(NULL), diff --git a/lldb/source/DataFormatters/LibCxxVector.cpp b/lldb/source/DataFormatters/LibCxxVector.cpp new file mode 100644 index 000000000000..3d488421915b --- /dev/null +++ b/lldb/source/DataFormatters/LibCxxVector.cpp @@ -0,0 +1,157 @@ +//===-- LibCxxVector.cpp -----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/lldb-python.h" + +#include "lldb/DataFormatters/CXXFormatterFunctions.h" + +#include "lldb/Core/ConstString.h" +#include "lldb/Core/ValueObject.h" + +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::formatters; + +namespace lldb_private { + namespace formatters { + class LibcxxStdVectorSyntheticFrontEnd : public SyntheticChildrenFrontEnd + { + public: + LibcxxStdVectorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp); + + virtual size_t + CalculateNumChildren (); + + virtual lldb::ValueObjectSP + GetChildAtIndex (size_t idx); + + virtual bool + Update(); + + virtual bool + MightHaveChildren (); + + virtual size_t + GetIndexOfChildWithName (const ConstString &name); + + virtual + ~LibcxxStdVectorSyntheticFrontEnd (); + private: + ValueObject* m_start; + ValueObject* m_finish; + ClangASTType m_element_type; + uint32_t m_element_size; + std::map m_children; + }; + } +} + +lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::LibcxxStdVectorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) : +SyntheticChildrenFrontEnd(*valobj_sp.get()), +m_start(NULL), +m_finish(NULL), +m_element_type(), +m_element_size(0), +m_children() +{ + if (valobj_sp) + Update(); +} + +size_t +lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::CalculateNumChildren () +{ + if (!m_start || !m_finish) + return 0; + uint64_t start_val = m_start->GetValueAsUnsigned(0); + uint64_t finish_val = m_finish->GetValueAsUnsigned(0); + + if (start_val == 0 || finish_val == 0) + return 0; + + if (start_val >= finish_val) + return 0; + + size_t num_children = (finish_val - start_val); + if (num_children % m_element_size) + return 0; + return num_children/m_element_size; +} + +lldb::ValueObjectSP +lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::GetChildAtIndex (size_t idx) +{ + if (!m_start || !m_finish) + return lldb::ValueObjectSP(); + + auto cached = m_children.find(idx); + if (cached != m_children.end()) + return cached->second; + + uint64_t offset = idx * m_element_size; + offset = offset + m_start->GetValueAsUnsigned(0); + StreamString name; + name.Printf("[%" PRIu64 "]", (uint64_t)idx); + ValueObjectSP child_sp = ValueObject::CreateValueObjectFromAddress(name.GetData(), offset, m_backend.GetExecutionContextRef(), m_element_type); + m_children[idx] = child_sp; + return child_sp; +} + +bool +lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::Update() +{ + m_start = m_finish = NULL; + m_children.clear(); + ValueObjectSP data_type_finder_sp(m_backend.GetChildMemberWithName(ConstString("__end_cap_"),true)); + if (!data_type_finder_sp) + return false; + data_type_finder_sp = data_type_finder_sp->GetChildMemberWithName(ConstString("__first_"),true); + if (!data_type_finder_sp) + return false; + m_element_type = data_type_finder_sp->GetClangType().GetPointeeType(); + m_element_size = m_element_type.GetByteSize(); + + if (m_element_size > 0) + { + // store raw pointers or end up with a circular dependency + m_start = m_backend.GetChildMemberWithName(ConstString("__begin_"),true).get(); + m_finish = m_backend.GetChildMemberWithName(ConstString("__end_"),true).get(); + } + return false; +} + +bool +lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::MightHaveChildren () +{ + return true; +} + +size_t +lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name) +{ + if (!m_start || !m_finish) + return UINT32_MAX; + return ExtractIndexFromString(name.GetCString()); +} + +lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::~LibcxxStdVectorSyntheticFrontEnd () +{ + // these need to stay around because they are child objects who will follow their parent's life cycle + // delete m_start; + // delete m_finish; +} + +lldb_private::SyntheticChildrenFrontEnd* +lldb_private::formatters::LibcxxStdVectorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp) +{ + if (!valobj_sp) + return NULL; + return (new LibcxxStdVectorSyntheticFrontEnd(valobj_sp)); +} + diff --git a/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/initializerlist/TestInitializerList.py b/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/initializerlist/TestInitializerList.py new file mode 100644 index 000000000000..a70d2ca74147 --- /dev/null +++ b/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/initializerlist/TestInitializerList.py @@ -0,0 +1,3 @@ +import lldbinline + +lldbinline.MakeInlineTest(__file__, globals()) diff --git a/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/initializerlist/main.cpp b/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/initializerlist/main.cpp new file mode 100644 index 000000000000..f89bb2c62fbe --- /dev/null +++ b/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/initializerlist/main.cpp @@ -0,0 +1,21 @@ +//===-- main.cpp --------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include +#include +#include + +int main () +{ + std::initializer_list ili{1,2,3,4,5}; + std::initializer_list ils{"1","2","3","4","surprise it is a long string!! yay!!"}; + + return 0; //% self.expect("frame variable ili", substrs = ['[1] = 2','[4] = 5']) + //% self.expect("frame variable ils", substrs = ['[4] = "surprise it is a long string!! yay!!"']) +}