http://llvm.org/bugs/show_bug.cgi?id=11588
valobj.AddressOf() returns None when an address is expected in a SyntheticChildrenProvider
Patch from Enrico Granata:
The problem was that the frozen object created by the expression parser was a copy of the contents of the StgClosure, rather than a pointer to it. Thus, the expression parser was correctly computing the result of the arithmetic&cast operation along with its address, but only saving it in the live object. This meant that the frozen copy acted as an address-less variable, hence the problem.
The fix attached to this email lets the expression parser store the "live address" in the frozen copy of the address when the object is built without a valid address of its own.
Doing so, along with delegating ValueObjectConstResult to calculate its own address when necessary, solves the issue. I have also added a new test case to check for regressions in this area, and checked that existing test cases pass correctly.
git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@146768 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Core/ValueObjectConstResult.cpp b/source/Core/ValueObjectConstResult.cpp
index 9a23ca8..fa1503f 100644
--- a/source/Core/ValueObjectConstResult.cpp
+++ b/source/Core/ValueObjectConstResult.cpp
@@ -324,6 +324,13 @@
return m_impl.AddressOf(error);
}
+lldb::addr_t
+ValueObjectConstResult::GetAddressOf (bool scalar_is_load_address,
+ AddressType *address_type)
+{
+ return m_impl.GetAddressOf(scalar_is_load_address, address_type);
+}
+
ValueObject *
ValueObjectConstResult::CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index)
{
diff --git a/source/Core/ValueObjectConstResultImpl.cpp b/source/Core/ValueObjectConstResultImpl.cpp
index 119ba01..afe0502 100644
--- a/source/Core/ValueObjectConstResultImpl.cpp
+++ b/source/Core/ValueObjectConstResultImpl.cpp
@@ -40,7 +40,8 @@
ValueObjectConstResultImpl::ValueObjectConstResultImpl (ValueObject* valobj,
lldb::addr_t live_address) :
m_impl_backend(valobj),
- m_live_address(live_address),
+ m_live_address(live_address),
+ m_live_address_type(eAddressTypeLoad),
m_load_addr_backend(),
m_address_of_backend()
{
@@ -201,6 +202,26 @@
return lldb::ValueObjectSP();
}
+lldb::addr_t
+ValueObjectConstResultImpl::GetAddressOf (bool scalar_is_load_address,
+ AddressType *address_type)
+{
+
+ if (m_impl_backend == NULL)
+ return 0;
+
+ if (m_live_address == LLDB_INVALID_ADDRESS)
+ {
+ return m_impl_backend->ValueObject::GetAddressOf (scalar_is_load_address,
+ address_type);
+ }
+
+ if (address_type)
+ *address_type = m_live_address_type;
+
+ return m_live_address;
+}
+
size_t
ValueObjectConstResultImpl::GetPointeeData (DataExtractor& data,
uint32_t item_idx,
diff --git a/source/Expression/ClangExpressionDeclMap.cpp b/source/Expression/ClangExpressionDeclMap.cpp
index e019334..e115054 100644
--- a/source/Expression/ClangExpressionDeclMap.cpp
+++ b/source/Expression/ClangExpressionDeclMap.cpp
@@ -396,13 +396,23 @@
{
// The reference comes from the program. We need to set up a live SP for it.
+ unsigned long long address = value.GetScalar().ULongLong();
+ AddressType address_type = value.GetValueAddressType();
+
pvar_sp->m_live_sp = ValueObjectConstResult::Create(m_parser_vars->m_exe_ctx->GetBestExecutionContextScope(),
pvar_sp->GetTypeFromUser().GetASTContext(),
pvar_sp->GetTypeFromUser().GetOpaqueQualType(),
pvar_sp->GetName(),
- value.GetScalar().ULongLong(),
- value.GetValueAddressType(),
+ address,
+ address_type,
pvar_sp->GetByteSize());
+
+ // if the frozen object does not yet have a valid live address we replicate the live_sp address
+ // to it. this solves the issue where synthetic children providers are unable to access
+ // the address-of result for objects obtained by casting the result of pointer arithmetic
+ // performed by the expression parser, as in: print *((ClassType*)(value-1))
+ if (pvar_sp->m_frozen_sp->GetLiveAddress() == LLDB_INVALID_ADDRESS)
+ pvar_sp->m_frozen_sp->SetLiveAddress(address);
}
if (pvar_sp->m_flags & ClangExpressionVariable::EVNeedsFreezeDry)