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/Core/ValueObjectSyntheticFilter.h"
14 // Other libraries and framework includes
16 #include "lldb/Core/ValueObject.h"
17 #include "lldb/DataFormatters/TypeSynthetic.h"
19 using namespace lldb_private;
21 class DummySyntheticFrontEnd : public SyntheticChildrenFrontEnd
24 DummySyntheticFrontEnd(ValueObject &backend) :
25 SyntheticChildrenFrontEnd(backend)
29 CalculateNumChildren()
31 return m_backend.GetNumChildren();
35 GetChildAtIndex (size_t idx)
37 return m_backend.GetChildAtIndex(idx, true);
41 GetIndexOfChildWithName (const ConstString &name)
43 return m_backend.GetIndexOfChildWithName(name);
60 ValueObjectSynthetic::ValueObjectSynthetic (ValueObject &parent, lldb::SyntheticChildrenSP filter) :
65 m_synthetic_children_count(UINT32_MAX),
66 m_parent_type_name(parent.GetTypeName()),
67 m_might_have_children(eLazyBoolCalculate),
68 m_provides_value(eLazyBoolCalculate)
71 std::string new_name(parent.GetName().AsCString());
72 new_name += "$$__synth__";
73 SetName (ConstString(new_name.c_str()));
75 SetName(parent.GetName());
77 CopyValueData(m_parent);
81 ValueObjectSynthetic::~ValueObjectSynthetic()
86 ValueObjectSynthetic::GetClangTypeImpl ()
88 return m_parent->GetClangType();
92 ValueObjectSynthetic::GetTypeName()
94 return m_parent->GetTypeName();
98 ValueObjectSynthetic::GetQualifiedTypeName()
100 return m_parent->GetQualifiedTypeName();
104 ValueObjectSynthetic::GetDisplayTypeName()
106 return m_parent->GetDisplayTypeName();
110 ValueObjectSynthetic::CalculateNumChildren()
112 UpdateValueIfNeeded();
113 if (m_synthetic_children_count < UINT32_MAX)
114 return m_synthetic_children_count;
115 return (m_synthetic_children_count = m_synth_filter_ap->CalculateNumChildren());
119 ValueObjectSynthetic::GetDynamicValue (lldb::DynamicValueType valueType)
122 return lldb::ValueObjectSP();
123 if (IsDynamic() && GetDynamicValueType() == valueType)
125 return m_parent->GetDynamicValue(valueType);
129 ValueObjectSynthetic::MightHaveChildren()
131 if (m_might_have_children == eLazyBoolCalculate)
132 m_might_have_children = (m_synth_filter_ap->MightHaveChildren() ? eLazyBoolYes : eLazyBoolNo);
133 return (m_might_have_children == eLazyBoolNo ? false : true);
137 ValueObjectSynthetic::GetByteSize()
139 return m_parent->GetByteSize();
143 ValueObjectSynthetic::GetValueType() const
145 return m_parent->GetValueType();
149 ValueObjectSynthetic::CreateSynthFilter ()
151 m_synth_filter_ap = (m_synth_sp->GetFrontEnd(*m_parent));
152 if (!m_synth_filter_ap.get())
153 m_synth_filter_ap.reset(new DummySyntheticFrontEnd(*m_parent));
157 ValueObjectSynthetic::UpdateValue ()
159 SetValueIsValid (false);
162 if (!m_parent->UpdateValueIfNeeded(false))
164 // our parent could not update.. as we are meaningless without a parent, just stop
165 if (m_parent->GetError().Fail())
166 m_error = m_parent->GetError();
170 // regenerate the synthetic filter if our typename changes
171 // <rdar://problem/12424824>
172 ConstString new_parent_type_name = m_parent->GetTypeName();
173 if (new_parent_type_name != m_parent_type_name)
175 m_parent_type_name = new_parent_type_name;
179 // let our backend do its update
180 if (m_synth_filter_ap->Update() == false)
182 // filter said that cached values are stale
183 m_children_byindex.Clear();
184 m_name_toindex.Clear();
185 // usually, an object's value can change but this does not alter its children count
186 // for a synthetic VO that might indeed happen, so we need to tell the upper echelons
187 // that they need to come back to us asking for children
188 m_children_count_valid = false;
189 m_synthetic_children_count = UINT32_MAX;
190 m_might_have_children = eLazyBoolCalculate;
193 m_provides_value = eLazyBoolCalculate;
195 lldb::ValueObjectSP synth_val(m_synth_filter_ap->GetSyntheticValue());
197 if (synth_val && synth_val->CanProvideValue())
199 m_provides_value = eLazyBoolYes;
200 CopyValueData(synth_val.get());
204 m_provides_value = eLazyBoolNo;
205 CopyValueData(m_parent);
208 SetValueIsValid(true);
213 ValueObjectSynthetic::GetChildAtIndex (size_t idx, bool can_create)
215 UpdateValueIfNeeded();
218 if (m_children_byindex.GetValueForKey(idx, valobj) == false)
220 if (can_create && m_synth_filter_ap.get() != NULL)
222 lldb::ValueObjectSP synth_guy = m_synth_filter_ap->GetChildAtIndex (idx);
225 m_children_byindex.SetValueForKey(idx, synth_guy.get());
229 return lldb::ValueObjectSP();
232 return valobj->GetSP();
236 ValueObjectSynthetic::GetChildMemberWithName (const ConstString &name, bool can_create)
238 UpdateValueIfNeeded();
240 uint32_t index = GetIndexOfChildWithName(name);
242 if (index == UINT32_MAX)
243 return lldb::ValueObjectSP();
245 return GetChildAtIndex(index, can_create);
249 ValueObjectSynthetic::GetIndexOfChildWithName (const ConstString &name)
251 UpdateValueIfNeeded();
253 uint32_t found_index = UINT32_MAX;
254 bool did_find = m_name_toindex.GetValueForKey(name.GetCString(), found_index);
256 if (!did_find && m_synth_filter_ap.get() != NULL)
258 uint32_t index = m_synth_filter_ap->GetIndexOfChildWithName (name);
259 if (index == UINT32_MAX)
261 m_name_toindex.SetValueForKey(name.GetCString(), index);
264 else if (!did_find && m_synth_filter_ap.get() == NULL)
266 else /*if (iter != m_name_toindex.end())*/
271 ValueObjectSynthetic::IsInScope ()
273 return m_parent->IsInScope();
277 ValueObjectSynthetic::GetNonSyntheticValue ()
279 return m_parent->GetSP();
283 ValueObjectSynthetic::CopyValueData (ValueObject *source)
285 m_value = (source->UpdateValueIfNeeded(), source->GetValue());
286 ExecutionContext exe_ctx (GetExecutionContextRef());
287 m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get());
291 ValueObjectSynthetic::CanProvideValue ()
293 if (!UpdateValueIfNeeded())
295 if (m_provides_value == eLazyBoolYes)
297 return m_parent->CanProvideValue();
301 ValueObjectSynthetic::SetValueFromCString (const char *value_str, Error& error)
303 return m_parent->SetValueFromCString(value_str, error);
307 ValueObjectSynthetic::SetFormat (lldb::Format format)
311 m_parent->ClearUserVisibleData(eClearUserVisibleDataItemsAll);
312 m_parent->SetFormat(format);
314 this->ValueObject::SetFormat(format);
315 this->ClearUserVisibleData(eClearUserVisibleDataItemsAll);