| //===-- ValueObjectSyntheticFilter.cpp -----------------------------*- C++ -*-===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| |
| #include "lldb/Core/ValueObjectSyntheticFilter.h" |
| |
| // C Includes |
| // C++ Includes |
| // Other libraries and framework includes |
| // Project includes |
| #include "lldb/Core/FormatClasses.h" |
| #include "lldb/Core/ValueObject.h" |
| |
| using namespace lldb_private; |
| |
| ValueObjectSynthetic::ValueObjectSynthetic (ValueObject &parent, lldb::SyntheticChildrenSP filter) : |
| ValueObject(parent), |
| m_synth_sp(filter), |
| m_synth_filter_ap(filter->GetFrontEnd(parent)), |
| m_children_byindex(), |
| m_name_toindex(), |
| m_synthetic_children_count(UINT32_MAX) |
| { |
| #ifdef LLDB_CONFIGURATION_DEBUG |
| std::string new_name(parent.GetName().AsCString()); |
| new_name += "$$__synth__"; |
| SetName (ConstString(new_name.c_str())); |
| #else |
| SetName(parent.GetName()); |
| #endif |
| } |
| |
| ValueObjectSynthetic::~ValueObjectSynthetic() |
| { |
| } |
| |
| lldb::clang_type_t |
| ValueObjectSynthetic::GetClangTypeImpl () |
| { |
| return m_parent->GetClangType(); |
| } |
| |
| ConstString |
| ValueObjectSynthetic::GetTypeName() |
| { |
| return m_parent->GetTypeName(); |
| } |
| |
| uint32_t |
| ValueObjectSynthetic::CalculateNumChildren() |
| { |
| UpdateValueIfNeeded(); |
| if (m_synthetic_children_count < UINT32_MAX) |
| return m_synthetic_children_count; |
| return (m_synthetic_children_count = m_synth_filter_ap->CalculateNumChildren()); |
| } |
| |
| clang::ASTContext * |
| ValueObjectSynthetic::GetClangASTImpl () |
| { |
| return m_parent->GetClangAST (); |
| } |
| |
| size_t |
| ValueObjectSynthetic::GetByteSize() |
| { |
| return m_parent->GetByteSize(); |
| } |
| |
| lldb::ValueType |
| ValueObjectSynthetic::GetValueType() const |
| { |
| return m_parent->GetValueType(); |
| } |
| |
| bool |
| ValueObjectSynthetic::UpdateValue () |
| { |
| SetValueIsValid (false); |
| m_error.Clear(); |
| |
| if (!m_parent->UpdateValueIfNeeded(false)) |
| { |
| // our parent could not update.. as we are meaningless without a parent, just stop |
| if (m_parent->GetError().Fail()) |
| m_error = m_parent->GetError(); |
| return false; |
| } |
| |
| // let our backend do its update |
| if (m_synth_filter_ap->Update() == false) |
| { |
| // filter said that cached values are stale |
| m_children_byindex.clear(); |
| m_name_toindex.clear(); |
| // usually, an object's value can change but this does not alter its children count |
| // for a synthetic VO that might indeed happen, so we need to tell the upper echelons |
| // that they need to come back to us asking for children |
| m_children_count_valid = false; |
| m_synthetic_children_count = UINT32_MAX; |
| } |
| |
| SetValueIsValid(true); |
| return true; |
| } |
| |
| lldb::ValueObjectSP |
| ValueObjectSynthetic::GetChildAtIndex (uint32_t idx, bool can_create) |
| { |
| UpdateValueIfNeeded(); |
| |
| ByIndexIterator iter = m_children_byindex.find(idx); |
| |
| if (iter == m_children_byindex.end()) |
| { |
| if (can_create && m_synth_filter_ap.get() != NULL) |
| { |
| lldb::ValueObjectSP synth_guy = m_synth_filter_ap->GetChildAtIndex (idx, can_create); |
| if (!synth_guy) |
| return synth_guy; |
| m_children_byindex[idx]= synth_guy.get(); |
| return synth_guy; |
| } |
| else |
| return lldb::ValueObjectSP(); |
| } |
| else |
| return iter->second->GetSP(); |
| } |
| |
| lldb::ValueObjectSP |
| ValueObjectSynthetic::GetChildMemberWithName (const ConstString &name, bool can_create) |
| { |
| UpdateValueIfNeeded(); |
| |
| uint32_t index = GetIndexOfChildWithName(name); |
| |
| if (index == UINT32_MAX) |
| return lldb::ValueObjectSP(); |
| |
| return GetChildAtIndex(index, can_create); |
| } |
| |
| uint32_t |
| ValueObjectSynthetic::GetIndexOfChildWithName (const ConstString &name) |
| { |
| UpdateValueIfNeeded(); |
| |
| NameToIndexIterator iter = m_name_toindex.find(name.GetCString()); |
| |
| if (iter == m_name_toindex.end() && m_synth_filter_ap.get() != NULL) |
| { |
| uint32_t index = m_synth_filter_ap->GetIndexOfChildWithName (name); |
| if (index == UINT32_MAX) |
| return index; |
| m_name_toindex[name.GetCString()] = index; |
| return index; |
| } |
| else if (iter == m_name_toindex.end() && m_synth_filter_ap.get() == NULL) |
| return UINT32_MAX; |
| else /*if (iter != m_name_toindex.end())*/ |
| return iter->second; |
| } |
| |
| bool |
| ValueObjectSynthetic::IsInScope () |
| { |
| return m_parent->IsInScope(); |
| } |
| |