blob: 56eb9f6c56e4b1df99e64b72687bbb3c1ebfe9b7 [file] [log] [blame]
//===-- 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();
}