Extend ValueObject::GetExpressionPath() to do something reasonable for synthetic children

Because of the way they are created, synthetic children cannot (in general) have a sane expression path

A solution to this would be letting the parent front-end generate expression paths for its children
Doing so requires a significant amount of refactoring, and might not always lead to better results (esp. w.r.t. C++ templates)

This commit takes a simpler approach:
- if a synthetic child is of pointer type and it's a target pointer, then emit *((T)value)
- if a synthetic child is a non-pointer, but its location is in the target, then emit *((T*)loadAddr)
- if a synthetic child has a value, emit ((T)value)
- else, don't emit anything

Fixes rdar://18442386

llvm-svn: 223836
This commit is contained in:
Enrico Granata
2014-12-09 21:41:16 +00:00
parent 93e9cf8aa4
commit 986fa5f4eb
3 changed files with 63 additions and 0 deletions

View File

@@ -2540,6 +2540,46 @@ ValueObject::IsBaseClass (uint32_t& depth)
void
ValueObject::GetExpressionPath (Stream &s, bool qualify_cxx_base_classes, GetExpressionPathFormat epformat)
{
// synthetic children do not actually "exist" as part of the hierarchy, and sometimes they are consed up in ways
// that don't make sense from an underlying language/API standpoint. So, use a special code path here to return
// something that can hopefully be used in expression
if (m_is_synthetic_children_generated)
{
UpdateValueIfNeeded();
if (m_value.GetValueType() == Value::eValueTypeLoadAddress)
{
if (IsPointerOrReferenceType())
{
s.Printf("((%s)0x%" PRIx64 ")",
GetTypeName().AsCString("void"),
GetValueAsUnsigned(0));
return;
}
else
{
uint64_t load_addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
if (load_addr != LLDB_INVALID_ADDRESS)
{
s.Printf("(*( (%s *)0x%" PRIx64 "))",
GetTypeName().AsCString("void"),
load_addr);
return;
}
}
}
if (CanProvideValue())
{
s.Printf("((%s)%s)",
GetTypeName().AsCString("void"),
GetValueAsCString());
return;
}
return;
}
const bool is_deref_of_parent = IsDereferenceOfParent ();
if (is_deref_of_parent && epformat == eGetExpressionPathFormatDereferencePointers)