forked from OSchip/llvm-project
Added the ability to get synthetic child values from SBValue objects that
represent pointers and arrays by adding an extra parameter to the SBValue SBValue::GetChildAtIndex (uint32_t idx, DynamicValueType use_dynamic, bool can_create_synthetic); The new "can_create_synthetic" will allow you to create child values that aren't actually a part of the original type. So if you code like: int *foo_ptr = ... And you have a SBValue that contains the value for "foo_ptr": SBValue foo_value = ... You can now get the "foo_ptr[12]" item by doing this: v = foo_value.GetChiltAtIndex (12, lldb.eNoDynamicValues, True); Normall the "foo_value" would only have one child value (an integer), but we can create "synthetic" child values by treating the pointer as an array. Likewise if you have code like: int array[2]; array_value = .... v = array_value.GetChiltAtIndex (0); // Success, v will be valid v = array_value.GetChiltAtIndex (1); // Success, v will be valid v = array_value.GetChiltAtIndex (2); // Fail, v won't be valid, "2" is not a valid zero based index in "array" But if you use the ability to create synthetic children: v = array_value.GetChiltAtIndex (0, lldb.eNoDynamicValues, True); // Success, v will be valid v = array_value.GetChiltAtIndex (1, lldb.eNoDynamicValues, True); // Success, v will be valid v = array_value.GetChiltAtIndex (2, lldb.eNoDynamicValues, True); // Success, v will be valid llvm-svn: 135292
This commit is contained in:
parent
b45111556d
commit
f660248238
|
@ -150,8 +150,60 @@ public:
|
|||
lldb::SBValue
|
||||
GetChildAtIndex (uint32_t idx);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Get a child value by index from a value.
|
||||
///
|
||||
/// Structs, unions, classes, arrays and and pointers have child
|
||||
/// values that can be access by index.
|
||||
///
|
||||
/// Structs and unions access child members using a zero based index
|
||||
/// for each child member. For
|
||||
///
|
||||
/// Classes reserve the first indexes for base classes that have
|
||||
/// members (empty base classes are omitted), and all members of the
|
||||
/// current class will then follow the base classes.
|
||||
///
|
||||
/// Pointers differ depending on what they point to. If the pointer
|
||||
/// points to a simple type, the child at index zero
|
||||
/// is the only child value available, unless \a synthetic_allowed
|
||||
/// is \b true, in which case the pointer will be used as an array
|
||||
/// and can create "synthetic" child values using positive or
|
||||
/// negative indexes. If the pointer points to an aggregate type
|
||||
/// (an array, class, union, struct), then the pointee is
|
||||
/// transparently skipped and any children are going to be the indexes
|
||||
/// of the child values within the aggregate type. For example if
|
||||
/// we have a "Point" type and we have a SBValue that contains a
|
||||
/// pointer to a "Point" type, then the child at index zero will be
|
||||
/// the "x" member, and the child at index 1 will be the "y" member
|
||||
/// (the child at index zero won't be a "Point" instance).
|
||||
///
|
||||
/// Arrays have a preset number of children that can be accessed by
|
||||
/// index and will returns invalid child values for indexes that are
|
||||
/// out of bounds unless the \a synthetic_allowed is \b true. In this
|
||||
/// case the array can create "synthetic" child values for indexes
|
||||
/// that aren't in the array bounds using positive or negative
|
||||
/// indexes.
|
||||
///
|
||||
/// @param[in] idx
|
||||
/// The index of the child value to get
|
||||
///
|
||||
/// @param[in] use_dynamic
|
||||
/// An enumeration that specifies wether to get dynamic values,
|
||||
/// and also if the target can be run to figure out the dynamic
|
||||
/// type of the child value.
|
||||
///
|
||||
/// @param[in] synthetic_allowed
|
||||
/// If \b true, then allow child values to be created by index
|
||||
/// for pointers and arrays for indexes that normally wouldn't
|
||||
/// be allowed.
|
||||
///
|
||||
/// @return
|
||||
/// A new SBValue object that represents the child member value.
|
||||
//------------------------------------------------------------------
|
||||
lldb::SBValue
|
||||
GetChildAtIndex (uint32_t idx, lldb::DynamicValueType use_dynamic);
|
||||
GetChildAtIndex (uint32_t idx,
|
||||
lldb::DynamicValueType use_dynamic,
|
||||
bool can_create_synthetic);
|
||||
|
||||
// Matches children of this object only and will match base classes and
|
||||
// member names if this is a clang typed object.
|
||||
|
|
|
@ -361,17 +361,15 @@ SBValue::SetValueFromCString (const char *value_str)
|
|||
SBValue
|
||||
SBValue::GetChildAtIndex (uint32_t idx)
|
||||
{
|
||||
const bool can_create_synthetic = false;
|
||||
lldb::DynamicValueType use_dynamic = eNoDynamicValues;
|
||||
if (m_opaque_sp)
|
||||
{
|
||||
lldb::DynamicValueType use_dynamic_value = m_opaque_sp->GetUpdatePoint().GetTarget()->GetPreferDynamicValue();
|
||||
return GetChildAtIndex (idx, use_dynamic_value);
|
||||
}
|
||||
else
|
||||
return GetChildAtIndex (idx, eNoDynamicValues);
|
||||
use_dynamic = m_opaque_sp->GetUpdatePoint().GetTarget()->GetPreferDynamicValue();
|
||||
return GetChildAtIndex (idx, use_dynamic, can_create_synthetic);
|
||||
}
|
||||
|
||||
SBValue
|
||||
SBValue::GetChildAtIndex (uint32_t idx, lldb::DynamicValueType use_dynamic)
|
||||
SBValue::GetChildAtIndex (uint32_t idx, lldb::DynamicValueType use_dynamic, bool can_create_synthetic)
|
||||
{
|
||||
lldb::ValueObjectSP child_sp;
|
||||
|
||||
|
@ -380,13 +378,25 @@ SBValue::GetChildAtIndex (uint32_t idx, lldb::DynamicValueType use_dynamic)
|
|||
if (m_opaque_sp->GetUpdatePoint().GetTarget())
|
||||
{
|
||||
Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex());
|
||||
|
||||
child_sp = m_opaque_sp->GetChildAtIndex (idx, true);
|
||||
if (use_dynamic != lldb::eNoDynamicValues)
|
||||
const bool can_create = true;
|
||||
child_sp = m_opaque_sp->GetChildAtIndex (idx, can_create);
|
||||
if (can_create_synthetic && !child_sp)
|
||||
{
|
||||
if (child_sp)
|
||||
if (m_opaque_sp->IsPointerType())
|
||||
{
|
||||
lldb::ValueObjectSP dynamic_sp = child_sp->GetDynamicValue (use_dynamic);
|
||||
child_sp = m_opaque_sp->GetSyntheticArrayMemberFromPointer(idx, can_create);
|
||||
}
|
||||
else if (m_opaque_sp->IsArrayType())
|
||||
{
|
||||
child_sp = m_opaque_sp->GetSyntheticArrayMemberFromArray(idx, can_create);
|
||||
}
|
||||
}
|
||||
|
||||
if (child_sp)
|
||||
{
|
||||
if (use_dynamic != lldb::eNoDynamicValues)
|
||||
{
|
||||
lldb::ValueObjectSP dynamic_sp(child_sp->GetDynamicValue (use_dynamic));
|
||||
if (dynamic_sp)
|
||||
child_sp = dynamic_sp;
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ def fuzz_obj(obj):
|
|||
obj.GetLocation()
|
||||
obj.SetValueFromCString("my_new_value")
|
||||
obj.GetChildAtIndex(1)
|
||||
obj.GetChildAtIndex(2, lldb.eNoDynamicValues)
|
||||
obj.GetChildAtIndex(2, lldb.eNoDynamicValues, False)
|
||||
obj.GetIndexOfChildWithName("my_first_child")
|
||||
obj.GetChildMemberWithName("my_first_child")
|
||||
obj.GetChildMemberWithName("my_first_child", lldb.eNoDynamicValues)
|
||||
|
|
Loading…
Reference in New Issue