]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/DataFormatters/LibCxxVector.cpp
Update mandoc to 20160116
[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/DataFormatters/CXXFormatterFunctions.h"
11
12 #include "lldb/Core/ConstString.h"
13 #include "lldb/Core/ValueObject.h"
14
15 using namespace lldb;
16 using namespace lldb_private;
17 using namespace lldb_private::formatters;
18
19 namespace 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;
46             ClangASTType m_element_type;
47             uint32_t m_element_size;
48             std::map<size_t,lldb::ValueObjectSP> m_children;
49         };
50     }
51 }
52
53 lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::LibcxxStdVectorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
54 SyntheticChildrenFrontEnd(*valobj_sp.get()),
55 m_start(NULL),
56 m_finish(NULL),
57 m_element_type(),
58 m_element_size(0),
59 m_children()
60 {
61     if (valobj_sp)
62         Update();
63 }
64
65 size_t
66 lldb_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
85 lldb::ValueObjectSP
86 lldb_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);
99     ValueObjectSP child_sp = CreateValueObjectFromAddress(name.GetData(), offset, m_backend.GetExecutionContextRef(), m_element_type);
100     m_children[idx] = child_sp;
101     return child_sp;
102 }
103
104 bool
105 lldb_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();
116     m_element_size = m_element_type.GetByteSize(nullptr);
117     
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
127 bool
128 lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::MightHaveChildren ()
129 {
130     return true;
131 }
132
133 size_t
134 lldb_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
141 lldb_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
148 lldb_private::SyntheticChildrenFrontEnd*
149 lldb_private::formatters::LibcxxStdVectorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
150 {
151     if (!valobj_sp)
152         return NULL;
153     return (new LibcxxStdVectorSyntheticFrontEnd(valobj_sp));
154 }
155