1 //===-- LibCxxVector.cpp -----------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "lldb/lldb-python.h"
12 #include "lldb/DataFormatters/CXXFormatterFunctions.h"
14 #include "lldb/Core/ConstString.h"
15 #include "lldb/Core/ValueObject.h"
18 using namespace lldb_private;
19 using namespace lldb_private::formatters;
21 namespace lldb_private {
22 namespace formatters {
23 class LibcxxStdVectorSyntheticFrontEnd : public SyntheticChildrenFrontEnd
26 LibcxxStdVectorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
29 CalculateNumChildren ();
31 virtual lldb::ValueObjectSP
32 GetChildAtIndex (size_t idx);
41 GetIndexOfChildWithName (const ConstString &name);
44 ~LibcxxStdVectorSyntheticFrontEnd ();
47 ValueObject* m_finish;
48 ClangASTType m_element_type;
49 uint32_t m_element_size;
50 std::map<size_t,lldb::ValueObjectSP> m_children;
55 lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::LibcxxStdVectorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
56 SyntheticChildrenFrontEnd(*valobj_sp.get()),
68 lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::CalculateNumChildren ()
70 if (!m_start || !m_finish)
72 uint64_t start_val = m_start->GetValueAsUnsigned(0);
73 uint64_t finish_val = m_finish->GetValueAsUnsigned(0);
75 if (start_val == 0 || finish_val == 0)
78 if (start_val >= finish_val)
81 size_t num_children = (finish_val - start_val);
82 if (num_children % m_element_size)
84 return num_children/m_element_size;
88 lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::GetChildAtIndex (size_t idx)
90 if (!m_start || !m_finish)
91 return lldb::ValueObjectSP();
93 auto cached = m_children.find(idx);
94 if (cached != m_children.end())
95 return cached->second;
97 uint64_t offset = idx * m_element_size;
98 offset = offset + m_start->GetValueAsUnsigned(0);
100 name.Printf("[%" PRIu64 "]", (uint64_t)idx);
101 ValueObjectSP child_sp = CreateValueObjectFromAddress(name.GetData(), offset, m_backend.GetExecutionContextRef(), m_element_type);
102 m_children[idx] = child_sp;
107 lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::Update()
109 m_start = m_finish = NULL;
111 ValueObjectSP data_type_finder_sp(m_backend.GetChildMemberWithName(ConstString("__end_cap_"),true));
112 if (!data_type_finder_sp)
114 data_type_finder_sp = data_type_finder_sp->GetChildMemberWithName(ConstString("__first_"),true);
115 if (!data_type_finder_sp)
117 m_element_type = data_type_finder_sp->GetClangType().GetPointeeType();
118 m_element_size = m_element_type.GetByteSize();
120 if (m_element_size > 0)
122 // store raw pointers or end up with a circular dependency
123 m_start = m_backend.GetChildMemberWithName(ConstString("__begin_"),true).get();
124 m_finish = m_backend.GetChildMemberWithName(ConstString("__end_"),true).get();
130 lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::MightHaveChildren ()
136 lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
138 if (!m_start || !m_finish)
140 return ExtractIndexFromString(name.GetCString());
143 lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::~LibcxxStdVectorSyntheticFrontEnd ()
145 // these need to stay around because they are child objects who will follow their parent's life cycle
150 lldb_private::SyntheticChildrenFrontEnd*
151 lldb_private::formatters::LibcxxStdVectorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
155 return (new LibcxxStdVectorSyntheticFrontEnd(valobj_sp));