blob: 950dcee7860562adfa1c6c6846ccc891fc40df75 [file] [log] [blame]
Eugene Zelenko8d15f332015-10-20 01:10:59 +00001//===-- LibCxxVector.cpp ----------------------------------------*- C++ -*-===//
Enrico Granatae85fe3a2014-10-22 20:34:38 +00002//
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
Eugene Zelenko8d15f332015-10-20 01:10:59 +000010// C Includes
11// C++ Includes
12// Other libraries and framework includes
13// Project includes
Enrico Granata33e97e62015-09-04 21:01:18 +000014#include "LibCxx.h"
Enrico Granatae85fe3a2014-10-22 20:34:38 +000015
16#include "lldb/Core/ConstString.h"
17#include "lldb/Core/ValueObject.h"
Enrico Granata419d7912015-09-04 00:33:51 +000018#include "lldb/DataFormatters/FormattersHelpers.h"
Enrico Granatae85fe3a2014-10-22 20:34:38 +000019
20using namespace lldb;
21using namespace lldb_private;
22using namespace lldb_private::formatters;
23
24namespace lldb_private {
Kate Stoneb9c1b512016-09-06 20:57:50 +000025namespace formatters {
26class LibcxxStdVectorSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
27public:
28 LibcxxStdVectorSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
Eugene Zelenko8d15f332015-10-20 01:10:59 +000029
Kate Stoneb9c1b512016-09-06 20:57:50 +000030 ~LibcxxStdVectorSyntheticFrontEnd() override;
Eugene Zelenko8d15f332015-10-20 01:10:59 +000031
Kate Stoneb9c1b512016-09-06 20:57:50 +000032 size_t CalculateNumChildren() override;
Eugene Zelenko8d15f332015-10-20 01:10:59 +000033
Kate Stoneb9c1b512016-09-06 20:57:50 +000034 lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
35
36 bool Update() override;
37
38 bool MightHaveChildren() override;
39
40 size_t GetIndexOfChildWithName(const ConstString &name) override;
41
42private:
43 ValueObject *m_start;
44 ValueObject *m_finish;
45 CompilerType m_element_type;
46 uint32_t m_element_size;
47};
48} // namespace formatters
Eugene Zelenko8d15f332015-10-20 01:10:59 +000049} // namespace lldb_private
Enrico Granatae85fe3a2014-10-22 20:34:38 +000050
Kate Stoneb9c1b512016-09-06 20:57:50 +000051lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::
52 LibcxxStdVectorSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
53 : SyntheticChildrenFrontEnd(*valobj_sp), m_start(nullptr),
54 m_finish(nullptr), m_element_type(), m_element_size(0) {
55 if (valobj_sp)
56 Update();
Enrico Granatae85fe3a2014-10-22 20:34:38 +000057}
58
Kate Stoneb9c1b512016-09-06 20:57:50 +000059lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::
60 ~LibcxxStdVectorSyntheticFrontEnd() {
61 // these need to stay around because they are child objects who will follow
62 // their parent's life cycle
63 // delete m_start;
64 // delete m_finish;
Eugene Zelenko8d15f332015-10-20 01:10:59 +000065}
66
Kate Stoneb9c1b512016-09-06 20:57:50 +000067size_t lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::
68 CalculateNumChildren() {
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;
Enrico Granatae85fe3a2014-10-22 20:34:38 +000084}
85
86lldb::ValueObjectSP
Kate Stoneb9c1b512016-09-06 20:57:50 +000087lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::GetChildAtIndex(
88 size_t idx) {
89 if (!m_start || !m_finish)
90 return lldb::ValueObjectSP();
91
92 uint64_t offset = idx * m_element_size;
93 offset = offset + m_start->GetValueAsUnsigned(0);
94 StreamString name;
95 name.Printf("[%" PRIu64 "]", (uint64_t)idx);
96 return CreateValueObjectFromAddress(name.GetData(), offset,
97 m_backend.GetExecutionContextRef(),
98 m_element_type);
Enrico Granatae85fe3a2014-10-22 20:34:38 +000099}
100
Kate Stoneb9c1b512016-09-06 20:57:50 +0000101bool lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::Update() {
102 m_start = m_finish = nullptr;
103 ValueObjectSP data_type_finder_sp(
104 m_backend.GetChildMemberWithName(ConstString("__end_cap_"), true));
105 if (!data_type_finder_sp)
Enrico Granatae85fe3a2014-10-22 20:34:38 +0000106 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000107 data_type_finder_sp = data_type_finder_sp->GetChildMemberWithName(
108 ConstString("__first_"), true);
109 if (!data_type_finder_sp)
110 return false;
111 m_element_type = data_type_finder_sp->GetCompilerType().GetPointeeType();
112 m_element_size = m_element_type.GetByteSize(nullptr);
113
114 if (m_element_size > 0) {
115 // store raw pointers or end up with a circular dependency
116 m_start =
117 m_backend.GetChildMemberWithName(ConstString("__begin_"), true).get();
118 m_finish =
119 m_backend.GetChildMemberWithName(ConstString("__end_"), true).get();
120 }
121 return false;
Enrico Granatae85fe3a2014-10-22 20:34:38 +0000122}
123
Kate Stoneb9c1b512016-09-06 20:57:50 +0000124bool lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::
125 MightHaveChildren() {
126 return true;
Enrico Granatae85fe3a2014-10-22 20:34:38 +0000127}
128
Kate Stoneb9c1b512016-09-06 20:57:50 +0000129size_t lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::
130 GetIndexOfChildWithName(const ConstString &name) {
131 if (!m_start || !m_finish)
132 return UINT32_MAX;
133 return ExtractIndexFromString(name.GetCString());
Enrico Granatae85fe3a2014-10-22 20:34:38 +0000134}
135
Kate Stoneb9c1b512016-09-06 20:57:50 +0000136lldb_private::SyntheticChildrenFrontEnd *
137lldb_private::formatters::LibcxxStdVectorSyntheticFrontEndCreator(
138 CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
139 return (valobj_sp ? new LibcxxStdVectorSyntheticFrontEnd(valobj_sp)
140 : nullptr);
Enrico Granatae85fe3a2014-10-22 20:34:38 +0000141}