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