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/FormatClasses.h"
21 using namespace lldb_private;
23 class DummySyntheticFrontEnd : public SyntheticChildrenFrontEnd
26 DummySyntheticFrontEnd(ValueObject &backend) :
27 SyntheticChildrenFrontEnd(backend)
31 CalculateNumChildren()
37 GetChildAtIndex (size_t idx)
39 return lldb::ValueObjectSP();
43 GetIndexOfChildWithName (const ConstString &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)
71 #ifdef LLDB_CONFIGURATION_DEBUG
72 std::string new_name(parent.GetName().AsCString());
73 new_name += "$$__synth__";
74 SetName (ConstString(new_name.c_str()));
76 SetName(parent.GetName());
82 ValueObjectSynthetic::~ValueObjectSynthetic()
87 ValueObjectSynthetic::GetClangTypeImpl ()
89 return m_parent->GetClangType();
93 ValueObjectSynthetic::GetTypeName()
95 return m_parent->GetTypeName();
99 ValueObjectSynthetic::GetQualifiedTypeName()
101 return m_parent->GetQualifiedTypeName();
105 ValueObjectSynthetic::CalculateNumChildren()
107 UpdateValueIfNeeded();
108 if (m_synthetic_children_count < UINT32_MAX)
109 return m_synthetic_children_count;
110 return (m_synthetic_children_count = m_synth_filter_ap->CalculateNumChildren());
114 ValueObjectSynthetic::GetDynamicValue (lldb::DynamicValueType valueType)
117 return lldb::ValueObjectSP();
118 if (IsDynamic() && GetDynamicValueType() == valueType)
120 return m_parent->GetDynamicValue(valueType);
124 ValueObjectSynthetic::MightHaveChildren()
126 if (m_might_have_children == eLazyBoolCalculate)
127 m_might_have_children = (m_synth_filter_ap->MightHaveChildren() ? eLazyBoolYes : eLazyBoolNo);
128 return (m_might_have_children == eLazyBoolNo ? false : true);
132 ValueObjectSynthetic::GetByteSize()
134 return m_parent->GetByteSize();
138 ValueObjectSynthetic::GetValueType() const
140 return m_parent->GetValueType();
144 ValueObjectSynthetic::CreateSynthFilter ()
146 m_synth_filter_ap = (m_synth_sp->GetFrontEnd(*m_parent));
147 if (!m_synth_filter_ap.get())
148 m_synth_filter_ap.reset(new DummySyntheticFrontEnd(*m_parent));
152 ValueObjectSynthetic::UpdateValue ()
154 SetValueIsValid (false);
157 if (!m_parent->UpdateValueIfNeeded(false))
159 // our parent could not update.. as we are meaningless without a parent, just stop
160 if (m_parent->GetError().Fail())
161 m_error = m_parent->GetError();
165 // regenerate the synthetic filter if our typename changes
166 // <rdar://problem/12424824>
167 ConstString new_parent_type_name = m_parent->GetTypeName();
168 if (new_parent_type_name != m_parent_type_name)
170 m_parent_type_name = new_parent_type_name;
174 // let our backend do its update
175 if (m_synth_filter_ap->Update() == false)
177 // filter said that cached values are stale
178 m_children_byindex.clear();
179 m_name_toindex.clear();
180 // usually, an object's value can change but this does not alter its children count
181 // for a synthetic VO that might indeed happen, so we need to tell the upper echelons
182 // that they need to come back to us asking for children
183 m_children_count_valid = false;
184 m_synthetic_children_count = UINT32_MAX;
185 m_might_have_children = eLazyBoolCalculate;
190 SetValueIsValid(true);
195 ValueObjectSynthetic::GetChildAtIndex (size_t idx, bool can_create)
197 UpdateValueIfNeeded();
199 ByIndexIterator iter = m_children_byindex.find(idx);
201 if (iter == m_children_byindex.end())
203 if (can_create && m_synth_filter_ap.get() != NULL)
205 lldb::ValueObjectSP synth_guy = m_synth_filter_ap->GetChildAtIndex (idx);
208 m_children_byindex[idx]= synth_guy.get();
212 return lldb::ValueObjectSP();
215 return iter->second->GetSP();
219 ValueObjectSynthetic::GetChildMemberWithName (const ConstString &name, bool can_create)
221 UpdateValueIfNeeded();
223 uint32_t index = GetIndexOfChildWithName(name);
225 if (index == UINT32_MAX)
226 return lldb::ValueObjectSP();
228 return GetChildAtIndex(index, can_create);
232 ValueObjectSynthetic::GetIndexOfChildWithName (const ConstString &name)
234 UpdateValueIfNeeded();
236 NameToIndexIterator iter = m_name_toindex.find(name.GetCString());
238 if (iter == m_name_toindex.end() && m_synth_filter_ap.get() != NULL)
240 uint32_t index = m_synth_filter_ap->GetIndexOfChildWithName (name);
241 if (index == UINT32_MAX)
243 m_name_toindex[name.GetCString()] = index;
246 else if (iter == m_name_toindex.end() && m_synth_filter_ap.get() == NULL)
248 else /*if (iter != m_name_toindex.end())*/
253 ValueObjectSynthetic::IsInScope ()
255 return m_parent->IsInScope();
259 ValueObjectSynthetic::GetNonSyntheticValue ()
261 return m_parent->GetSP();
265 ValueObjectSynthetic::CopyParentData ()
267 m_value = m_parent->GetValue();
268 ExecutionContext exe_ctx (GetExecutionContextRef());
269 m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get());