diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp --- a/lldb/source/Core/ValueObject.cpp +++ b/lldb/source/Core/ValueObject.cpp @@ -231,6 +231,10 @@ // We have to clear the value string here so ConstResult children will notice // if their values are changed by hand (i.e. with SetValueAsCString). ClearUserVisibleData(eClearUserVisibleDataItemsValue); + // Children have to be re-computed after updating the parent value. + m_flags.m_children_count_valid = false; + m_children.Clear(); + SetSyntheticChildren(lldb::SyntheticChildrenSP()); } void ValueObject::ClearDynamicTypeInformation() { diff --git a/lldb/test/API/python_api/value/change_values/TestChangeValueAPI.py b/lldb/test/API/python_api/value/change_values/TestChangeValueAPI.py --- a/lldb/test/API/python_api/value/change_values/TestChangeValueAPI.py +++ b/lldb/test/API/python_api/value/change_values/TestChangeValueAPI.py @@ -130,6 +130,41 @@ self.assertEquals(actual_value, 98765, "Got the right changed value from ptr->second_val") + # Test updating the children after updating the parent value. + def test_update_parent_value(parent): + self.assertEquals( + parent.GetValue(), + frame0.FindVariable("b1").GetValue()) + self.assertEquals(parent.GetChildAtIndex(0).GetValue(), "1") + + result = parent.SetValueFromCString( + frame0.FindVariable("b2").GetValue()) + self.assertTrue(result, "Success setting {}".format(parent.name)) + self.assertEquals( + parent.GetValue(), + frame0.FindVariable("b2").GetValue()) + self.assertEquals(parent.GetChildAtIndex(0).GetValue(), "2") + + # Test for value returned by SBFrame::EvaluateExpression. + test_update_parent_value( + frame0.EvaluateExpression("auto $b_0 = b1; $b_0")) + + # Test for value _created_ by SBFrame::EvaluateExpression. + frame0.EvaluateExpression("auto $b_0 = b1") + test_update_parent_value( + frame0.FindValue('$b_0', lldb.eValueTypeConstResult)) + + # Test for value created by SBTarget::CreateValueFromData. + b1 = frame0.FindVariable("b1") + b1_size = b1.GetByteSize() + b1_value = b1.GetValueAsUnsigned() + b1_addr_bytes = b1_value.to_bytes(b1_size, 'little') + error = lldb.SBError() + data = lldb.SBData() + data.SetData(error, b1_addr_bytes, lldb.eByteOrderLittle, b1_size) + test_update_parent_value( + target.CreateValueFromData("b", data, b1.GetType())) + # gcc may set multiple locations for breakpoint breakpoint.SetEnabled(False) diff --git a/lldb/test/API/python_api/value/change_values/main.c b/lldb/test/API/python_api/value/change_values/main.c --- a/lldb/test/API/python_api/value/change_values/main.c +++ b/lldb/test/API/python_api/value/change_values/main.c @@ -8,7 +8,12 @@ uint32_t second_val; uint64_t third_val; }; - + +struct bar +{ + int value; +}; + int main () { int val = 100; @@ -18,6 +23,11 @@ ptr->second_val = 6666; ptr->third_val = 66666666; + struct bar _b1 = {.value = 1}; + struct bar _b2 = {.value = 2}; + struct bar *b1 = &_b1; + struct bar *b2 = &_b2; + // Stop here and set values printf ("Val - %d Mine - %d, %d, %llu. Ptr - %d, %d, %llu\n", val, mine.first_val, mine.second_val, mine.third_val,