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/DataFormatters/CXXFormatterFunctions.h"
12 #include "lldb/Core/ConstString.h"
13 #include "lldb/Core/ValueObject.h"
16 using namespace lldb_private;
17 using namespace lldb_private::formatters;
19 namespace lldb_private {
20 namespace formatters {
21 class LibcxxStdVectorSyntheticFrontEnd : public SyntheticChildrenFrontEnd
24 LibcxxStdVectorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
27 CalculateNumChildren ();
29 virtual lldb::ValueObjectSP
30 GetChildAtIndex (size_t idx);
39 GetIndexOfChildWithName (const ConstString &name);
42 ~LibcxxStdVectorSyntheticFrontEnd ();
45 ValueObject* m_finish;
46 ClangASTType m_element_type;
47 uint32_t m_element_size;
48 std::map<size_t,lldb::ValueObjectSP> m_children;
53 lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::LibcxxStdVectorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
54 SyntheticChildrenFrontEnd(*valobj_sp.get()),
66 lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::CalculateNumChildren ()
68 if (!m_start || !m_finish)
70 uint64_t start_val = m_start->GetValueAsUnsigned(0);
71 uint64_t finish_val = m_finish->GetValueAsUnsigned(0);
73 if (start_val == 0 || finish_val == 0)
76 if (start_val >= finish_val)
79 size_t num_children = (finish_val - start_val);
80 if (num_children % m_element_size)
82 return num_children/m_element_size;
86 lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::GetChildAtIndex (size_t idx)
88 if (!m_start || !m_finish)
89 return lldb::ValueObjectSP();
91 auto cached = m_children.find(idx);
92 if (cached != m_children.end())
93 return cached->second;
95 uint64_t offset = idx * m_element_size;
96 offset = offset + m_start->GetValueAsUnsigned(0);
98 name.Printf("[%" PRIu64 "]", (uint64_t)idx);
99 ValueObjectSP child_sp = CreateValueObjectFromAddress(name.GetData(), offset, m_backend.GetExecutionContextRef(), m_element_type);
100 m_children[idx] = child_sp;
105 lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::Update()
107 m_start = m_finish = NULL;
109 ValueObjectSP data_type_finder_sp(m_backend.GetChildMemberWithName(ConstString("__end_cap_"),true));
110 if (!data_type_finder_sp)
112 data_type_finder_sp = data_type_finder_sp->GetChildMemberWithName(ConstString("__first_"),true);
113 if (!data_type_finder_sp)
115 m_element_type = data_type_finder_sp->GetClangType().GetPointeeType();
116 m_element_size = m_element_type.GetByteSize(nullptr);
118 if (m_element_size > 0)
120 // store raw pointers or end up with a circular dependency
121 m_start = m_backend.GetChildMemberWithName(ConstString("__begin_"),true).get();
122 m_finish = m_backend.GetChildMemberWithName(ConstString("__end_"),true).get();
128 lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::MightHaveChildren ()
134 lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
136 if (!m_start || !m_finish)
138 return ExtractIndexFromString(name.GetCString());
141 lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::~LibcxxStdVectorSyntheticFrontEnd ()
143 // these need to stay around because they are child objects who will follow their parent's life cycle
148 lldb_private::SyntheticChildrenFrontEnd*
149 lldb_private::formatters::LibcxxStdVectorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
153 return (new LibcxxStdVectorSyntheticFrontEnd(valobj_sp));