blob: 2461bf60a8f93d69429b59f0915de66ddf2d2045 [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 Granatae85fe3a2014-10-22 20:34:38 +000010#include "lldb/DataFormatters/CXXFormatterFunctions.h"
11
12#include "lldb/Core/ConstString.h"
13#include "lldb/Core/ValueObject.h"
14
15using namespace lldb;
16using namespace lldb_private;
17using namespace lldb_private::formatters;
18
19namespace lldb_private {
20 namespace formatters {
21 class LibcxxStdVectorSyntheticFrontEnd : public SyntheticChildrenFrontEnd
22 {
23 public:
24 LibcxxStdVectorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
25
26 virtual size_t
27 CalculateNumChildren ();
28
29 virtual lldb::ValueObjectSP
30 GetChildAtIndex (size_t idx);
31
32 virtual bool
33 Update();
34
35 virtual bool
36 MightHaveChildren ();
37
38 virtual size_t
39 GetIndexOfChildWithName (const ConstString &name);
40
41 virtual
42 ~LibcxxStdVectorSyntheticFrontEnd ();
43 private:
44 ValueObject* m_start;
45 ValueObject* m_finish;
Greg Claytona1e5dc82015-08-11 22:53:00 +000046 CompilerType m_element_type;
Enrico Granatae85fe3a2014-10-22 20:34:38 +000047 uint32_t m_element_size;
48 std::map<size_t,lldb::ValueObjectSP> m_children;
49 };
50 }
51}
52
53lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::LibcxxStdVectorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
54SyntheticChildrenFrontEnd(*valobj_sp.get()),
55m_start(NULL),
56m_finish(NULL),
57m_element_type(),
58m_element_size(0),
59m_children()
60{
61 if (valobj_sp)
62 Update();
63}
64
65size_t
66lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::CalculateNumChildren ()
67{
68 if (!m_start || !m_finish)
69 return 0;
70 uint64_t start_val = m_start->GetValueAsUnsigned(0);
71 uint64_t finish_val = m_finish->GetValueAsUnsigned(0);
72
73 if (start_val == 0 || finish_val == 0)
74 return 0;
75
76 if (start_val >= finish_val)
77 return 0;
78
79 size_t num_children = (finish_val - start_val);
80 if (num_children % m_element_size)
81 return 0;
82 return num_children/m_element_size;
83}
84
85lldb::ValueObjectSP
86lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::GetChildAtIndex (size_t idx)
87{
88 if (!m_start || !m_finish)
89 return lldb::ValueObjectSP();
90
91 auto cached = m_children.find(idx);
92 if (cached != m_children.end())
93 return cached->second;
94
95 uint64_t offset = idx * m_element_size;
96 offset = offset + m_start->GetValueAsUnsigned(0);
97 StreamString name;
98 name.Printf("[%" PRIu64 "]", (uint64_t)idx);
Enrico Granatae29df232014-12-09 19:51:20 +000099 ValueObjectSP child_sp = CreateValueObjectFromAddress(name.GetData(), offset, m_backend.GetExecutionContextRef(), m_element_type);
Enrico Granatae85fe3a2014-10-22 20:34:38 +0000100 m_children[idx] = child_sp;
101 return child_sp;
102}
103
104bool
105lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::Update()
106{
107 m_start = m_finish = NULL;
108 m_children.clear();
109 ValueObjectSP data_type_finder_sp(m_backend.GetChildMemberWithName(ConstString("__end_cap_"),true));
110 if (!data_type_finder_sp)
111 return false;
112 data_type_finder_sp = data_type_finder_sp->GetChildMemberWithName(ConstString("__first_"),true);
113 if (!data_type_finder_sp)
114 return false;
115 m_element_type = data_type_finder_sp->GetClangType().GetPointeeType();
Enrico Granata1cd5e922015-01-28 00:07:51 +0000116 m_element_size = m_element_type.GetByteSize(nullptr);
Enrico Granatae85fe3a2014-10-22 20:34:38 +0000117
118 if (m_element_size > 0)
119 {
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();
123 }
124 return false;
125}
126
127bool
128lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::MightHaveChildren ()
129{
130 return true;
131}
132
133size_t
134lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
135{
136 if (!m_start || !m_finish)
137 return UINT32_MAX;
138 return ExtractIndexFromString(name.GetCString());
139}
140
141lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::~LibcxxStdVectorSyntheticFrontEnd ()
142{
143 // these need to stay around because they are child objects who will follow their parent's life cycle
144 // delete m_start;
145 // delete m_finish;
146}
147
148lldb_private::SyntheticChildrenFrontEnd*
149lldb_private::formatters::LibcxxStdVectorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
150{
151 if (!valobj_sp)
152 return NULL;
153 return (new LibcxxStdVectorSyntheticFrontEnd(valobj_sp));
154}
155