summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/include/lldb/API/SBValue.h54
-rw-r--r--lldb/source/API/SBValue.cpp34
-rw-r--r--lldb/test/python_api/default-constructor/sb_value.py2
3 files changed, 76 insertions, 14 deletions
diff --git a/lldb/include/lldb/API/SBValue.h b/lldb/include/lldb/API/SBValue.h
index 9fce5bc2876..be869f89f00 100644
--- a/lldb/include/lldb/API/SBValue.h
+++ b/lldb/include/lldb/API/SBValue.h
@@ -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.
diff --git a/lldb/source/API/SBValue.cpp b/lldb/source/API/SBValue.cpp
index aeabb1740bf..5956784bbc7 100644
--- a/lldb/source/API/SBValue.cpp
+++ b/lldb/source/API/SBValue.cpp
@@ -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())
+ {
+ 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);
+ lldb::ValueObjectSP dynamic_sp(child_sp->GetDynamicValue (use_dynamic));
if (dynamic_sp)
child_sp = dynamic_sp;
}
diff --git a/lldb/test/python_api/default-constructor/sb_value.py b/lldb/test/python_api/default-constructor/sb_value.py
index f3929a6cb29..c2b90e59f39 100644
--- a/lldb/test/python_api/default-constructor/sb_value.py
+++ b/lldb/test/python_api/default-constructor/sb_value.py
@@ -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)
OpenPOWER on IntegriCloud