1 //===-- ValueObjectSyntheticFilter.cpp -----------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "lldb/lldb-python.h"
12 #include "lldb/Core/ValueObjectSyntheticFilter.h"
16 // Other libraries and framework includes
18 #include "lldb/Core/ValueObject.h"
19 #include "lldb/DataFormatters/TypeSynthetic.h"
21 using namespace lldb_private;
23 class DummySyntheticFrontEnd : public SyntheticChildrenFrontEnd
26 DummySyntheticFrontEnd(ValueObject &backend) :
27 SyntheticChildrenFrontEnd(backend)
31 CalculateNumChildren()
33 return m_backend.GetNumChildren();
37 GetChildAtIndex (size_t idx)
39 return m_backend.GetChildAtIndex(idx, true);
43 GetIndexOfChildWithName (const ConstString &name)
45 return m_backend.GetIndexOfChildWithName(name);
62 ValueObjectSynthetic::ValueObjectSynthetic (ValueObject &parent, lldb::SyntheticChildrenSP filter) :
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)
73 std::string new_name(parent.GetName().AsCString());
74 new_name += "$$__synth__";
75 SetName (ConstString(new_name.c_str()));
77 SetName(parent.GetName());
79 CopyValueData(m_parent);
83 ValueObjectSynthetic::~ValueObjectSynthetic()
88 ValueObjectSynthetic::GetClangTypeImpl ()
90 return m_parent->GetClangType();
94 ValueObjectSynthetic::GetTypeName()
96 return m_parent->GetTypeName();
100 ValueObjectSynthetic::GetQualifiedTypeName()
102 return m_parent->GetQualifiedTypeName();
106 ValueObjectSynthetic::GetDisplayTypeName()
108 return m_parent->GetDisplayTypeName();
112 ValueObjectSynthetic::CalculateNumChildren()
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());
121 ValueObjectSynthetic::GetDynamicValue (lldb::DynamicValueType valueType)
124 return lldb::ValueObjectSP();
125 if (IsDynamic() && GetDynamicValueType() == valueType)
127 return m_parent->GetDynamicValue(valueType);
131 ValueObjectSynthetic::MightHaveChildren()
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);
139 ValueObjectSynthetic::GetByteSize()
141 return m_parent->GetByteSize();
145 ValueObjectSynthetic::GetValueType() const
147 return m_parent->GetValueType();
151 ValueObjectSynthetic::CreateSynthFilter ()
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));
159 ValueObjectSynthetic::UpdateValue ()
161 SetValueIsValid (false);
164 if (!m_parent->UpdateValueIfNeeded(false))
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();
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)
177 m_parent_type_name = new_parent_type_name;
181 // let our backend do its update
182 if (m_synth_filter_ap->Update() == false)
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;
195 m_provides_value = eLazyBoolCalculate;
197 lldb::ValueObjectSP synth_val(m_synth_filter_ap->GetSyntheticValue());
199 if (synth_val && synth_val->CanProvideValue())
201 m_provides_value = eLazyBoolYes;
202 CopyValueData(synth_val.get());
206 m_provides_value = eLazyBoolNo;
207 CopyValueData(m_parent);
210 SetValueIsValid(true);
215 ValueObjectSynthetic::GetChildAtIndex (size_t idx, bool can_create)
217 UpdateValueIfNeeded();
220 if (m_children_byindex.GetValueForKey(idx, valobj) == false)
222 if (can_create && m_synth_filter_ap.get() != NULL)
224 lldb::ValueObjectSP synth_guy = m_synth_filter_ap->GetChildAtIndex (idx);
227 m_children_byindex.SetValueForKey(idx, synth_guy.get());
231 return lldb::ValueObjectSP();
234 return valobj->GetSP();
238 ValueObjectSynthetic::GetChildMemberWithName (const ConstString &name, bool can_create)
240 UpdateValueIfNeeded();
242 uint32_t index = GetIndexOfChildWithName(name);
244 if (index == UINT32_MAX)
245 return lldb::ValueObjectSP();
247 return GetChildAtIndex(index, can_create);
251 ValueObjectSynthetic::GetIndexOfChildWithName (const ConstString &name)
253 UpdateValueIfNeeded();
255 uint32_t found_index = UINT32_MAX;
256 bool did_find = m_name_toindex.GetValueForKey(name.GetCString(), found_index);
258 if (!did_find && m_synth_filter_ap.get() != NULL)
260 uint32_t index = m_synth_filter_ap->GetIndexOfChildWithName (name);
261 if (index == UINT32_MAX)
263 m_name_toindex.SetValueForKey(name.GetCString(), index);
266 else if (!did_find && m_synth_filter_ap.get() == NULL)
268 else /*if (iter != m_name_toindex.end())*/
273 ValueObjectSynthetic::IsInScope ()
275 return m_parent->IsInScope();
279 ValueObjectSynthetic::GetNonSyntheticValue ()
281 return m_parent->GetSP();
285 ValueObjectSynthetic::CopyValueData (ValueObject *source)
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());
293 ValueObjectSynthetic::CanProvideValue ()
295 if (!UpdateValueIfNeeded())
297 if (m_provides_value == eLazyBoolYes)
299 return m_parent->CanProvideValue();