diff options
-rw-r--r-- | lldb/include/lldb/API/SBValue.h | 54 | ||||
-rw-r--r-- | lldb/source/API/SBValue.cpp | 34 | ||||
-rw-r--r-- | lldb/test/python_api/default-constructor/sb_value.py | 2 |
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) |