summaryrefslogtreecommitdiffstats
path: root/source/Core/ValueObjectVariable.cpp
diff options
context:
space:
mode:
authoremaste <emaste@FreeBSD.org>2015-02-06 21:38:51 +0000
committeremaste <emaste@FreeBSD.org>2015-02-06 21:38:51 +0000
commit0c2019f4ca6b2dc6d710f6bb16a0e3ed10271531 (patch)
tree09bc83f73246ee3c7a779605cd0122093d2a8a19 /source/Core/ValueObjectVariable.cpp
parent01ee1789d6aa7294e5966a97f8d29387f6f81699 (diff)
downloadFreeBSD-src-0c2019f4ca6b2dc6d710f6bb16a0e3ed10271531.zip
FreeBSD-src-0c2019f4ca6b2dc6d710f6bb16a0e3ed10271531.tar.gz
Import LLDB as of upstream SVN r225923 (git 2b588ecd)
This corresponds with the branchpoint for the 3.6 release. A number of files not required for the FreeBSD build have been removed. Sponsored by: DARPA, AFRL
Diffstat (limited to 'source/Core/ValueObjectVariable.cpp')
-rw-r--r--source/Core/ValueObjectVariable.cpp43
1 files changed, 37 insertions, 6 deletions
diff --git a/source/Core/ValueObjectVariable.cpp b/source/Core/ValueObjectVariable.cpp
index 225dc02..ab74a50 100644
--- a/source/Core/ValueObjectVariable.cpp
+++ b/source/Core/ValueObjectVariable.cpp
@@ -171,14 +171,44 @@ ValueObjectVariable::UpdateValue ()
m_value.SetClangType(clang_type);
Value::ValueType value_type = m_value.GetValueType();
-
+
+ Process *process = exe_ctx.GetProcessPtr();
+ const bool process_is_alive = process && process->IsAlive();
+ const uint32_t type_info = clang_type.GetTypeInfo();
+ const bool is_pointer_or_ref = (type_info & (lldb::eTypeIsPointer | lldb::eTypeIsReference)) != 0;
+
switch (value_type)
{
case Value::eValueTypeFileAddress:
- SetAddressTypeOfChildren(eAddressTypeFile);
+ // If this type is a pointer, then its children will be considered load addresses
+ // if the pointer or reference is dereferenced, but only if the process is alive.
+ //
+ // There could be global variables like in the following code:
+ // struct LinkedListNode { Foo* foo; LinkedListNode* next; };
+ // Foo g_foo1;
+ // Foo g_foo2;
+ // LinkedListNode g_second_node = { &g_foo2, NULL };
+ // LinkedListNode g_first_node = { &g_foo1, &g_second_node };
+ //
+ // When we aren't running, we should be able to look at these variables using
+ // the "target variable" command. Children of the "g_first_node" always will
+ // be of the same address type as the parent. But children of the "next" member of
+ // LinkedListNode will become load addresses if we have a live process, or remain
+ // what a file address if it what a file address.
+ if (process_is_alive && is_pointer_or_ref)
+ SetAddressTypeOfChildren(eAddressTypeLoad);
+ else
+ SetAddressTypeOfChildren(eAddressTypeFile);
break;
case Value::eValueTypeHostAddress:
- SetAddressTypeOfChildren(eAddressTypeHost);
+ // Same as above for load addresses, except children of pointer or refs are always
+ // load addresses. Host addresses are used to store freeze dried variables. If this
+ // type is a struct, the entire struct contents will be copied into the heap of the
+ // LLDB process, but we do not currrently follow any pointers.
+ if (is_pointer_or_ref)
+ SetAddressTypeOfChildren(eAddressTypeLoad);
+ else
+ SetAddressTypeOfChildren(eAddressTypeHost);
break;
case Value::eValueTypeLoadAddress:
case Value::eValueTypeScalar:
@@ -209,8 +239,7 @@ ValueObjectVariable::UpdateValue ()
// Make sure this type has a value before we try and read it
// If we have a file address, convert it to a load address if we can.
- Process *process = exe_ctx.GetProcessPtr();
- if (value_type == Value::eValueTypeFileAddress && process && process->IsAlive())
+ if (value_type == Value::eValueTypeFileAddress && process_is_alive)
{
lldb::addr_t file_addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
if (file_addr != LLDB_INVALID_ADDRESS)
@@ -234,7 +263,7 @@ ValueObjectVariable::UpdateValue ()
}
}
- if (GetClangType().IsAggregateType())
+ if (!CanProvideValue())
{
// this value object represents an aggregate type whose
// children have values, but this object does not. So we
@@ -248,6 +277,8 @@ ValueObjectVariable::UpdateValue ()
Value value(m_value);
value.SetContext(Value::eContextTypeVariable, variable);
m_error = value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get());
+
+ SetValueDidChange (value_type != old_value.GetValueType() || m_value.GetScalar() != old_value.GetScalar());
}
break;
}
OpenPOWER on IntegriCloud