]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Core/ValueObjectSyntheticFilter.cpp
Update LLDB snapshot to upstream r225923 (git 2b588ecd)
[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     m_provides_value(eLazyBoolCalculate)
71 {
72 #ifdef FOOBAR
73     std::string new_name(parent.GetName().AsCString());
74     new_name += "$$__synth__";
75     SetName (ConstString(new_name.c_str()));
76 #else
77     SetName(parent.GetName());
78 #endif
79     CopyValueData(m_parent);
80     CreateSynthFilter();
81 }
82
83 ValueObjectSynthetic::~ValueObjectSynthetic()
84 {
85 }
86
87 ClangASTType
88 ValueObjectSynthetic::GetClangTypeImpl ()
89 {
90     return m_parent->GetClangType();
91 }
92
93 ConstString
94 ValueObjectSynthetic::GetTypeName()
95 {
96     return m_parent->GetTypeName();
97 }
98
99 ConstString
100 ValueObjectSynthetic::GetQualifiedTypeName()
101 {
102     return m_parent->GetQualifiedTypeName();
103 }
104
105 ConstString
106 ValueObjectSynthetic::GetDisplayTypeName()
107 {
108     return m_parent->GetDisplayTypeName();
109 }
110
111 size_t
112 ValueObjectSynthetic::CalculateNumChildren()
113 {
114     UpdateValueIfNeeded();
115     if (m_synthetic_children_count < UINT32_MAX)
116         return m_synthetic_children_count;
117     return (m_synthetic_children_count = m_synth_filter_ap->CalculateNumChildren());
118 }
119
120 lldb::ValueObjectSP
121 ValueObjectSynthetic::GetDynamicValue (lldb::DynamicValueType valueType)
122 {
123     if (!m_parent)
124         return lldb::ValueObjectSP();
125     if (IsDynamic() && GetDynamicValueType() == valueType)
126         return GetSP();
127     return m_parent->GetDynamicValue(valueType);
128 }
129
130 bool
131 ValueObjectSynthetic::MightHaveChildren()
132 {
133     if (m_might_have_children == eLazyBoolCalculate)
134         m_might_have_children = (m_synth_filter_ap->MightHaveChildren() ? eLazyBoolYes : eLazyBoolNo);
135     return (m_might_have_children == eLazyBoolNo ? false : true);
136 }
137
138 uint64_t
139 ValueObjectSynthetic::GetByteSize()
140 {
141     return m_parent->GetByteSize();
142 }
143
144 lldb::ValueType
145 ValueObjectSynthetic::GetValueType() const
146 {
147     return m_parent->GetValueType();
148 }
149
150 void
151 ValueObjectSynthetic::CreateSynthFilter ()
152 {
153     m_synth_filter_ap = (m_synth_sp->GetFrontEnd(*m_parent));
154     if (!m_synth_filter_ap.get())
155         m_synth_filter_ap.reset(new DummySyntheticFrontEnd(*m_parent));
156 }
157
158 bool
159 ValueObjectSynthetic::UpdateValue ()
160 {
161     SetValueIsValid (false);
162     m_error.Clear();
163
164     if (!m_parent->UpdateValueIfNeeded(false))
165     {
166         // our parent could not update.. as we are meaningless without a parent, just stop
167         if (m_parent->GetError().Fail())
168             m_error = m_parent->GetError();
169         return false;
170     }
171     
172     // regenerate the synthetic filter if our typename changes
173     // <rdar://problem/12424824>
174     ConstString new_parent_type_name = m_parent->GetTypeName();
175     if (new_parent_type_name != m_parent_type_name)
176     {
177         m_parent_type_name = new_parent_type_name;
178         CreateSynthFilter();
179     }
180
181     // let our backend do its update
182     if (m_synth_filter_ap->Update() == false)
183     {
184         // filter said that cached values are stale
185         m_children_byindex.Clear();
186         m_name_toindex.Clear();
187         // usually, an object's value can change but this does not alter its children count
188         // for a synthetic VO that might indeed happen, so we need to tell the upper echelons
189         // that they need to come back to us asking for children
190         m_children_count_valid = false;
191         m_synthetic_children_count = UINT32_MAX;
192         m_might_have_children = eLazyBoolCalculate;
193     }
194     
195     m_provides_value = eLazyBoolCalculate;
196     
197     lldb::ValueObjectSP synth_val(m_synth_filter_ap->GetSyntheticValue());
198     
199     if (synth_val && synth_val->CanProvideValue())
200     {
201         m_provides_value = eLazyBoolYes;
202         CopyValueData(synth_val.get());
203     }
204     else
205     {
206         m_provides_value = eLazyBoolNo;
207         CopyValueData(m_parent);
208     }
209     
210     SetValueIsValid(true);
211     return true;
212 }
213
214 lldb::ValueObjectSP
215 ValueObjectSynthetic::GetChildAtIndex (size_t idx, bool can_create)
216 {
217     UpdateValueIfNeeded();
218     
219     ValueObject *valobj;
220     if (m_children_byindex.GetValueForKey(idx, valobj) == false)
221     {
222         if (can_create && m_synth_filter_ap.get() != NULL)
223         {
224             lldb::ValueObjectSP synth_guy = m_synth_filter_ap->GetChildAtIndex (idx);
225             if (!synth_guy)
226                 return synth_guy;
227             m_children_byindex.SetValueForKey(idx, synth_guy.get());
228             return synth_guy;
229         }
230         else
231             return lldb::ValueObjectSP();
232     }
233     else
234         return valobj->GetSP();
235 }
236
237 lldb::ValueObjectSP
238 ValueObjectSynthetic::GetChildMemberWithName (const ConstString &name, bool can_create)
239 {
240     UpdateValueIfNeeded();
241
242     uint32_t index = GetIndexOfChildWithName(name);
243     
244     if (index == UINT32_MAX)
245         return lldb::ValueObjectSP();
246     
247     return GetChildAtIndex(index, can_create);
248 }
249
250 size_t
251 ValueObjectSynthetic::GetIndexOfChildWithName (const ConstString &name)
252 {
253     UpdateValueIfNeeded();
254     
255     uint32_t found_index = UINT32_MAX;
256     bool did_find = m_name_toindex.GetValueForKey(name.GetCString(), found_index);
257     
258     if (!did_find && m_synth_filter_ap.get() != NULL)
259     {
260         uint32_t index = m_synth_filter_ap->GetIndexOfChildWithName (name);
261         if (index == UINT32_MAX)
262             return index;
263         m_name_toindex.SetValueForKey(name.GetCString(), index);
264         return index;
265     }
266     else if (!did_find && m_synth_filter_ap.get() == NULL)
267         return UINT32_MAX;
268     else /*if (iter != m_name_toindex.end())*/
269         return found_index;
270 }
271
272 bool
273 ValueObjectSynthetic::IsInScope ()
274 {
275     return m_parent->IsInScope();
276 }
277
278 lldb::ValueObjectSP
279 ValueObjectSynthetic::GetNonSyntheticValue ()
280 {
281     return m_parent->GetSP();
282 }
283
284 void
285 ValueObjectSynthetic::CopyValueData (ValueObject *source)
286 {
287     m_value = (source->UpdateValueIfNeeded(), source->GetValue());
288     ExecutionContext exe_ctx (GetExecutionContextRef());
289     m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get());
290 }
291
292 bool
293 ValueObjectSynthetic::CanProvideValue ()
294 {
295     if (!UpdateValueIfNeeded())
296         return false;
297     if (m_provides_value == eLazyBoolYes)
298         return true;
299     return m_parent->CanProvideValue();
300 }