blob: 1e14fff60089b6aab6f2bad1515a8a1f3ea9d9d2 [file] [log] [blame]
Enrico Granatae85fe3a2014-10-22 20:34:38 +00001//===-- LibCxxVector.cpp -----------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Enrico Granata419d7912015-09-04 00:33:51 +000010#include "lldb/DataFormatters/LibCxx.h"
Enrico Granatae85fe3a2014-10-22 20:34:38 +000011
12#include "lldb/Core/ConstString.h"
13#include "lldb/Core/ValueObject.h"
Enrico Granata419d7912015-09-04 00:33:51 +000014#include "lldb/DataFormatters/FormattersHelpers.h"
Enrico Granatae85fe3a2014-10-22 20:34:38 +000015
16using namespace lldb;
17using namespace lldb_private;
18using namespace lldb_private::formatters;
19
20namespace lldb_private {
21 namespace formatters {
22 class LibcxxStdVectorSyntheticFrontEnd : public SyntheticChildrenFrontEnd
23 {
24 public:
25 LibcxxStdVectorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
26
27 virtual size_t
28 CalculateNumChildren ();
29
30 virtual lldb::ValueObjectSP
31 GetChildAtIndex (size_t idx);
32
33 virtual bool
34 Update();
35
36 virtual bool
37 MightHaveChildren ();
38
39 virtual size_t
40 GetIndexOfChildWithName (const ConstString &name);
41
42 virtual
43 ~LibcxxStdVectorSyntheticFrontEnd ();
44 private:
45 ValueObject* m_start;
46 ValueObject* m_finish;
Greg Claytona1e5dc82015-08-11 22:53:00 +000047 CompilerType m_element_type;
Enrico Granatae85fe3a2014-10-22 20:34:38 +000048 uint32_t m_element_size;
49 std::map<size_t,lldb::ValueObjectSP> m_children;
50 };
51 }
52}
53
54lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::LibcxxStdVectorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
55SyntheticChildrenFrontEnd(*valobj_sp.get()),
56m_start(NULL),
57m_finish(NULL),
58m_element_type(),
59m_element_size(0),
60m_children()
61{
62 if (valobj_sp)
63 Update();
64}
65
66size_t
67lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::CalculateNumChildren ()
68{
69 if (!m_start || !m_finish)
70 return 0;
71 uint64_t start_val = m_start->GetValueAsUnsigned(0);
72 uint64_t finish_val = m_finish->GetValueAsUnsigned(0);
73
74 if (start_val == 0 || finish_val == 0)
75 return 0;
76
77 if (start_val >= finish_val)
78 return 0;
79
80 size_t num_children = (finish_val - start_val);
81 if (num_children % m_element_size)
82 return 0;
83 return num_children/m_element_size;
84}
85
86lldb::ValueObjectSP
87lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::GetChildAtIndex (size_t idx)
88{
89 if (!m_start || !m_finish)
90 return lldb::ValueObjectSP();
91
92 auto cached = m_children.find(idx);
93 if (cached != m_children.end())
94 return cached->second;
95
96 uint64_t offset = idx * m_element_size;
97 offset = offset + m_start->GetValueAsUnsigned(0);
98 StreamString name;
99 name.Printf("[%" PRIu64 "]", (uint64_t)idx);
Enrico Granatae29df232014-12-09 19:51:20 +0000100 ValueObjectSP child_sp = CreateValueObjectFromAddress(name.GetData(), offset, m_backend.GetExecutionContextRef(), m_element_type);
Enrico Granatae85fe3a2014-10-22 20:34:38 +0000101 m_children[idx] = child_sp;
102 return child_sp;
103}
104
105bool
106lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::Update()
107{
108 m_start = m_finish = NULL;
109 m_children.clear();
110 ValueObjectSP data_type_finder_sp(m_backend.GetChildMemberWithName(ConstString("__end_cap_"),true));
111 if (!data_type_finder_sp)
112 return false;
113 data_type_finder_sp = data_type_finder_sp->GetChildMemberWithName(ConstString("__first_"),true);
114 if (!data_type_finder_sp)
115 return false;
Greg Clayton99558cc42015-08-24 23:46:31 +0000116 m_element_type = data_type_finder_sp->GetCompilerType().GetPointeeType();
Enrico Granata1cd5e922015-01-28 00:07:51 +0000117 m_element_size = m_element_type.GetByteSize(nullptr);
Enrico Granatae85fe3a2014-10-22 20:34:38 +0000118
119 if (m_element_size > 0)
120 {
121 // store raw pointers or end up with a circular dependency
122 m_start = m_backend.GetChildMemberWithName(ConstString("__begin_"),true).get();
123 m_finish = m_backend.GetChildMemberWithName(ConstString("__end_"),true).get();
124 }
125 return false;
126}
127
128bool
129lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::MightHaveChildren ()
130{
131 return true;
132}
133
134size_t
135lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
136{
137 if (!m_start || !m_finish)
138 return UINT32_MAX;
139 return ExtractIndexFromString(name.GetCString());
140}
141
142lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::~LibcxxStdVectorSyntheticFrontEnd ()
143{
144 // these need to stay around because they are child objects who will follow their parent's life cycle
145 // delete m_start;
146 // delete m_finish;
147}
148
149lldb_private::SyntheticChildrenFrontEnd*
150lldb_private::formatters::LibcxxStdVectorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
151{
152 if (!valobj_sp)
153 return NULL;
154 return (new LibcxxStdVectorSyntheticFrontEnd(valobj_sp));
155}
156