]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Core/ValueObjectSyntheticFilter.cpp
Update libucl to git version 8d3b186
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Core / ValueObjectSyntheticFilter.cpp
1 //===-- ValueObjectSyntheticFilter.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/Core/ValueObjectSyntheticFilter.h"
13
14 // C Includes
15 // C++ Includes
16 // Other libraries and framework includes
17 // Project includes
18 #include "lldb/Core/ValueObject.h"
19 #include "lldb/DataFormatters/TypeSynthetic.h"
20
21 using namespace lldb_private;
22
23 class DummySyntheticFrontEnd : public SyntheticChildrenFrontEnd
24 {
25 public:
26     DummySyntheticFrontEnd(ValueObject &backend) :
27     SyntheticChildrenFrontEnd(backend)
28     {}
29
30     size_t
31     CalculateNumChildren()
32     {
33         return m_backend.GetNumChildren();
34     }
35     
36     lldb::ValueObjectSP
37     GetChildAtIndex (size_t idx)
38     {
39         return m_backend.GetChildAtIndex(idx, true);
40     }
41     
42     size_t
43     GetIndexOfChildWithName (const ConstString &name)
44     {
45         return m_backend.GetIndexOfChildWithName(name);
46     }
47     
48     bool
49     MightHaveChildren ()
50     {
51         return true;
52     }
53     
54     bool
55     Update()
56     {
57         return false;
58     }
59
60 };
61
62 ValueObjectSynthetic::ValueObjectSynthetic (ValueObject &parent, lldb::SyntheticChildrenSP filter) :
63     ValueObject(parent),
64     m_synth_sp(filter),
65     m_children_byindex(),
66     m_name_toindex(),
67     m_synthetic_children_count(UINT32_MAX),
68     m_parent_type_name(parent.GetTypeName()),
69     m_might_have_children(eLazyBoolCalculate)
70 {
71 #ifdef LLDB_CONFIGURATION_DEBUG
72     std::string new_name(parent.GetName().AsCString());
73     new_name += "$$__synth__";
74     SetName (ConstString(new_name.c_str()));
75 #else
76     SetName(parent.GetName());
77 #endif
78     CopyParentData();
79     CreateSynthFilter();
80 }
81
82 ValueObjectSynthetic::~ValueObjectSynthetic()
83 {
84 }
85
86 ClangASTType
87 ValueObjectSynthetic::GetClangTypeImpl ()
88 {
89     return m_parent->GetClangType();
90 }
91
92 ConstString
93 ValueObjectSynthetic::GetTypeName()
94 {
95     return m_parent->GetTypeName();
96 }
97
98 ConstString
99 ValueObjectSynthetic::GetQualifiedTypeName()
100 {
101     return m_parent->GetQualifiedTypeName();
102 }
103
104 ConstString
105 ValueObjectSynthetic::GetDisplayTypeName()
106 {
107     return m_parent->GetDisplayTypeName();
108 }
109
110 size_t
111 ValueObjectSynthetic::CalculateNumChildren()
112 {
113     UpdateValueIfNeeded();
114     if (m_synthetic_children_count < UINT32_MAX)
115         return m_synthetic_children_count;
116     return (m_synthetic_children_count = m_synth_filter_ap->CalculateNumChildren());
117 }
118
119 lldb::ValueObjectSP
120 ValueObjectSynthetic::GetDynamicValue (lldb::DynamicValueType valueType)
121 {
122     if (!m_parent)
123         return lldb::ValueObjectSP();
124     if (IsDynamic() && GetDynamicValueType() == valueType)
125         return GetSP();
126     return m_parent->GetDynamicValue(valueType);
127 }
128
129 bool
130 ValueObjectSynthetic::MightHaveChildren()
131 {
132     if (m_might_have_children == eLazyBoolCalculate)
133         m_might_have_children = (m_synth_filter_ap->MightHaveChildren() ? eLazyBoolYes : eLazyBoolNo);
134     return (m_might_have_children == eLazyBoolNo ? false : true);
135 }
136
137 uint64_t
138 ValueObjectSynthetic::GetByteSize()
139 {
140     return m_parent->GetByteSize();
141 }
142
143 lldb::ValueType
144 ValueObjectSynthetic::GetValueType() const
145 {
146     return m_parent->GetValueType();
147 }
148
149 void
150 ValueObjectSynthetic::CreateSynthFilter ()
151 {
152     m_synth_filter_ap = (m_synth_sp->GetFrontEnd(*m_parent));
153     if (!m_synth_filter_ap.get())
154         m_synth_filter_ap.reset(new DummySyntheticFrontEnd(*m_parent));
155 }
156
157 bool
158 ValueObjectSynthetic::UpdateValue ()
159 {
160     SetValueIsValid (false);
161     m_error.Clear();
162
163     if (!m_parent->UpdateValueIfNeeded(false))
164     {
165         // our parent could not update.. as we are meaningless without a parent, just stop
166         if (m_parent->GetError().Fail())
167             m_error = m_parent->GetError();
168         return false;
169     }
170     
171     // regenerate the synthetic filter if our typename changes
172     // <rdar://problem/12424824>
173     ConstString new_parent_type_name = m_parent->GetTypeName();
174     if (new_parent_type_name != m_parent_type_name)
175     {
176         m_parent_type_name = new_parent_type_name;
177         CreateSynthFilter();
178     }
179
180     // let our backend do its update
181     if (m_synth_filter_ap->Update() == false)
182     {
183         // filter said that cached values are stale
184         m_children_byindex.clear();
185         m_name_toindex.clear();
186         // usually, an object's value can change but this does not alter its children count
187         // for a synthetic VO that might indeed happen, so we need to tell the upper echelons
188         // that they need to come back to us asking for children
189         m_children_count_valid = false;
190         m_synthetic_children_count = UINT32_MAX;
191         m_might_have_children = eLazyBoolCalculate;
192     }
193     
194     CopyParentData();
195     
196     SetValueIsValid(true);
197     return true;
198 }
199
200 lldb::ValueObjectSP
201 ValueObjectSynthetic::GetChildAtIndex (size_t idx, bool can_create)
202 {
203     UpdateValueIfNeeded();
204     
205     ByIndexIterator iter = m_children_byindex.find(idx);
206     
207     if (iter == m_children_byindex.end())
208     {
209         if (can_create && m_synth_filter_ap.get() != NULL)
210         {
211             lldb::ValueObjectSP synth_guy = m_synth_filter_ap->GetChildAtIndex (idx);
212             if (!synth_guy)
213                 return synth_guy;
214             m_children_byindex[idx]= synth_guy.get();
215             return synth_guy;
216         }
217         else
218             return lldb::ValueObjectSP();
219     }
220     else
221         return iter->second->GetSP();
222 }
223
224 lldb::ValueObjectSP
225 ValueObjectSynthetic::GetChildMemberWithName (const ConstString &name, bool can_create)
226 {
227     UpdateValueIfNeeded();
228
229     uint32_t index = GetIndexOfChildWithName(name);
230     
231     if (index == UINT32_MAX)
232         return lldb::ValueObjectSP();
233     
234     return GetChildAtIndex(index, can_create);
235 }
236
237 size_t
238 ValueObjectSynthetic::GetIndexOfChildWithName (const ConstString &name)
239 {
240     UpdateValueIfNeeded();
241     
242     NameToIndexIterator iter = m_name_toindex.find(name.GetCString());
243     
244     if (iter == m_name_toindex.end() && m_synth_filter_ap.get() != NULL)
245     {
246         uint32_t index = m_synth_filter_ap->GetIndexOfChildWithName (name);
247         if (index == UINT32_MAX)
248             return index;
249         m_name_toindex[name.GetCString()] = index;
250         return index;
251     }
252     else if (iter == m_name_toindex.end() && m_synth_filter_ap.get() == NULL)
253         return UINT32_MAX;
254     else /*if (iter != m_name_toindex.end())*/
255         return iter->second;
256 }
257
258 bool
259 ValueObjectSynthetic::IsInScope ()
260 {
261     return m_parent->IsInScope();
262 }
263
264 lldb::ValueObjectSP
265 ValueObjectSynthetic::GetNonSyntheticValue ()
266 {
267     return m_parent->GetSP();
268 }
269
270 void
271 ValueObjectSynthetic::CopyParentData ()
272 {
273     m_value = m_parent->GetValue();
274     ExecutionContext exe_ctx (GetExecutionContextRef());
275     m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get());
276 }