]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - source/Plugins/Language/CPlusPlus/LibCxxVector.cpp
Vendor import of lldb trunk r290819:
[FreeBSD/FreeBSD.git] / source / Plugins / Language / CPlusPlus / LibCxxVector.cpp
1 //===-- 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
10 // C Includes
11 // C++ Includes
12 // Other libraries and framework includes
13 // Project includes
14 #include "LibCxx.h"
15
16 #include "lldb/Core/ConstString.h"
17 #include "lldb/Core/ValueObject.h"
18 #include "lldb/DataFormatters/FormattersHelpers.h"
19
20 using namespace lldb;
21 using namespace lldb_private;
22 using namespace lldb_private::formatters;
23
24 namespace lldb_private {
25 namespace formatters {
26 class LibcxxStdVectorSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
27 public:
28   LibcxxStdVectorSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
29
30   ~LibcxxStdVectorSyntheticFrontEnd() override;
31
32   size_t CalculateNumChildren() override;
33
34   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
42 private:
43   ValueObject *m_start;
44   ValueObject *m_finish;
45   CompilerType m_element_type;
46   uint32_t m_element_size;
47 };
48 } // namespace formatters
49 } // namespace lldb_private
50
51 lldb_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();
57 }
58
59 lldb_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;
65 }
66
67 size_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;
84 }
85
86 lldb::ValueObjectSP
87 lldb_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.GetString(), offset,
97                                       m_backend.GetExecutionContextRef(),
98                                       m_element_type);
99 }
100
101 bool 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)
106     return false;
107   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;
122 }
123
124 bool lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::
125     MightHaveChildren() {
126   return true;
127 }
128
129 size_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());
134 }
135
136 lldb_private::SyntheticChildrenFrontEnd *
137 lldb_private::formatters::LibcxxStdVectorSyntheticFrontEndCreator(
138     CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
139   return (valobj_sp ? new LibcxxStdVectorSyntheticFrontEnd(valobj_sp)
140                     : nullptr);
141 }