https://github.com/kastiglione updated 
https://github.com/llvm/llvm-project/pull/197311

>From c2e0494e0153c7c3523c0c80d0577a38b7aa4248 Mon Sep 17 00:00:00 2001
From: Dave Lee <[email protected]>
Date: Tue, 12 May 2026 14:49:58 -0700
Subject: [PATCH 1/3] [lldb] Add SBValue::GetParent

---
 lldb/bindings/interface/SBValueExtensions.i   |  1 +
 lldb/include/lldb/API/SBValue.h               |  2 ++
 lldb/source/API/SBValue.cpp                   | 14 +++++++++
 .../python_api/sbvalue_get_parent/Makefile    |  2 ++
 .../TestSBValueGetParent.py                   | 30 +++++++++++++++++++
 .../python_api/sbvalue_get_parent/main.cpp    | 12 ++++++++
 6 files changed, 61 insertions(+)
 create mode 100644 lldb/test/API/python_api/sbvalue_get_parent/Makefile
 create mode 100644 
lldb/test/API/python_api/sbvalue_get_parent/TestSBValueGetParent.py
 create mode 100644 lldb/test/API/python_api/sbvalue_get_parent/main.cpp

diff --git a/lldb/bindings/interface/SBValueExtensions.i 
b/lldb/bindings/interface/SBValueExtensions.i
index f0c8797bd5f78..63e61141afec1 100644
--- a/lldb/bindings/interface/SBValueExtensions.i
+++ b/lldb/bindings/interface/SBValueExtensions.i
@@ -86,6 +86,7 @@ STRING_EXTENSION_OUTSIDE(SBValue)
         process = property(GetProcess, None, doc='''A read only property that 
returns the lldb.SBProcess that this value is associated with, the returned 
value might be invalid and should be tested.''')
         thread = property(GetThread, None, doc='''A read only property that 
returns the lldb.SBThread that this value is associated with, the returned 
value might be invalid and should be tested.''')
         frame = property(GetFrame, None, doc='''A read only property that 
returns the lldb.SBFrame that this value is associated with, the returned value 
might be invalid and should be tested.''')
+        parent = property(GetParent, None, doc='''A read only property that 
returns the lldb.SBValue that is the parent of this value.''')
         num_children = property(GetNumChildren, None, doc='''A read only 
property that returns the number of child lldb.SBValues that this value has.''')
         unsigned = property(GetValueAsUnsigned, None, doc='''A read only 
property that returns the value of this SBValue as an usigned integer.''')
         signed = property(GetValueAsSigned, None, doc='''A read only property 
that returns the value of this SBValue as a signed integer.''')
diff --git a/lldb/include/lldb/API/SBValue.h b/lldb/include/lldb/API/SBValue.h
index d4cc2f05c39e3..23a58897bc110 100644
--- a/lldb/include/lldb/API/SBValue.h
+++ b/lldb/include/lldb/API/SBValue.h
@@ -82,6 +82,8 @@ class LLDB_API SBValue {
 
   const char *GetObjectDescription();
 
+  lldb::SBValue GetParent();
+
   lldb::SBValue GetDynamicValue(lldb::DynamicValueType use_dynamic);
 
   lldb::SBValue GetStaticValue();
diff --git a/lldb/source/API/SBValue.cpp b/lldb/source/API/SBValue.cpp
index 4ee8b271c5aad..82792622177c6 100644
--- a/lldb/source/API/SBValue.cpp
+++ b/lldb/source/API/SBValue.cpp
@@ -598,6 +598,20 @@ SBValue::GetChildMemberWithName(const char *name,
   return sb_value;
 }
 
+lldb::SBValue SBValue::GetParent() {
+  LLDB_INSTRUMENT_VA(this);
+
+  SBValue sb_value;
+  ValueLocker locker;
+  lldb::ValueObjectSP value_sp(GetSP(locker));
+  if (value_sp) {
+    ValueObject *parent = value_sp->GetParent();
+    if (parent)
+      sb_value.SetSP(parent->GetSP());
+  }
+  return sb_value;
+}
+
 lldb::SBValue SBValue::GetDynamicValue(lldb::DynamicValueType use_dynamic) {
   LLDB_INSTRUMENT_VA(this, use_dynamic);
 
diff --git a/lldb/test/API/python_api/sbvalue_get_parent/Makefile 
b/lldb/test/API/python_api/sbvalue_get_parent/Makefile
new file mode 100644
index 0000000000000..3d0b98f13f3d7
--- /dev/null
+++ b/lldb/test/API/python_api/sbvalue_get_parent/Makefile
@@ -0,0 +1,2 @@
+CXX_SOURCES := main.cpp
+include Makefile.rules
diff --git 
a/lldb/test/API/python_api/sbvalue_get_parent/TestSBValueGetParent.py 
b/lldb/test/API/python_api/sbvalue_get_parent/TestSBValueGetParent.py
new file mode 100644
index 0000000000000..f40eddaabfbe0
--- /dev/null
+++ b/lldb/test/API/python_api/sbvalue_get_parent/TestSBValueGetParent.py
@@ -0,0 +1,30 @@
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class TestCase(TestBase):
+    NO_DEBUG_INFO_TESTCASE = True
+
+    def test(self):
+        self.build()
+        _, _, thread, _ = lldbutil.run_to_source_breakpoint(
+            self, "break here", lldb.SBFileSpec("main.cpp")
+        )
+        frame = thread.GetFrameAtIndex(0)
+
+        parent = frame.FindVariable("parent")
+        self.assertTrue(parent.IsValid())
+
+        child = parent.GetChildMemberWithName("child")
+        self.assertTrue(child.IsValid())
+
+        # GetParent of child should be the parent struct.
+        child_parent = child.GetParent()
+        self.assertTrue(child_parent.IsValid())
+        self.assertEqual(child_parent.name, "parent")
+        self.assertEqual(child_parent.GetID(), parent.GetID())
+
+        # GetParent of a top-level variable should be invalid.
+        self.assertFalse(parent.GetParent().IsValid())
diff --git a/lldb/test/API/python_api/sbvalue_get_parent/main.cpp 
b/lldb/test/API/python_api/sbvalue_get_parent/main.cpp
new file mode 100644
index 0000000000000..27318ae58f92c
--- /dev/null
+++ b/lldb/test/API/python_api/sbvalue_get_parent/main.cpp
@@ -0,0 +1,12 @@
+struct Child {
+  int x;
+};
+
+struct Parent {
+  Child child;
+};
+
+int main() {
+  Parent parent = {{1}};
+  return 0; // break here
+}

>From 282815ec169782d8dcdb1dd2003c9304a93ba845 Mon Sep 17 00:00:00 2001
From: Dave Lee <[email protected]>
Date: Mon, 18 May 2026 17:12:36 -0700
Subject: [PATCH 2/3] Fix GetParent for synthetic children

---
 lldb/include/lldb/ValueObject/ValueObject.h   | 14 +++++++++++--
 .../ValueObject/ValueObjectSynthetic.cpp      |  3 +++
 .../TestSBValueGetParent.py                   | 20 +++++++++++++------
 .../python_api/sbvalue_get_parent/main.cpp    |  3 +++
 4 files changed, 32 insertions(+), 8 deletions(-)

diff --git a/lldb/include/lldb/ValueObject/ValueObject.h 
b/lldb/include/lldb/ValueObject/ValueObject.h
index 029563fa77850..68a2682a81a93 100644
--- a/lldb/include/lldb/ValueObject/ValueObject.h
+++ b/lldb/include/lldb/ValueObject/ValueObject.h
@@ -913,9 +913,15 @@ class ValueObject {
   // update itself then use m_parent.  The ValueObjectDynamicValue's parent is
   // not the correct parent for displaying, they are really siblings, so for
   // display it needs to route through to its grandparent.
-  virtual ValueObject *GetParent() { return m_parent; }
+  virtual ValueObject *GetParent() {
+    return m_logical_parent ? m_logical_parent : m_parent;
+  }
+
+  virtual const ValueObject *GetParent() const {
+    return m_logical_parent ? m_logical_parent : m_parent;
+  }
 
-  virtual const ValueObject *GetParent() const { return m_parent; }
+  void SetLogicalParent(ValueObject *parent) { m_logical_parent = parent; }
 
   ValueObject *GetNonBaseClassParent();
 
@@ -1045,6 +1051,10 @@ class ValueObject {
 
   /// The parent value object, or nullptr if this has no parent.
   ValueObject *m_parent = nullptr;
+  /// The parent to report from GetParent(), if different from m_parent.
+  /// Used for synthetic children whose logical parent is the synthetic
+  /// ValueObject, not the infrastructure parent.
+  ValueObject *m_logical_parent = nullptr;
   /// The root of the hierarchy for this ValueObject (or nullptr if never
   /// calculated).
   ValueObject *m_root = nullptr;
diff --git a/lldb/source/ValueObject/ValueObjectSynthetic.cpp 
b/lldb/source/ValueObject/ValueObjectSynthetic.cpp
index bf7cc80537b17..1485dc1827480 100644
--- a/lldb/source/ValueObject/ValueObjectSynthetic.cpp
+++ b/lldb/source/ValueObject/ValueObjectSynthetic.cpp
@@ -286,6 +286,9 @@ lldb::ValueObjectSP 
ValueObjectSynthetic::GetChildAtIndex(uint32_t idx,
       if (!synth_guy)
         return synth_guy;
 
+      if (synth_guy->IsSyntheticChildrenGenerated())
+        synth_guy->SetLogicalParent(this);
+
       {
         std::lock_guard<std::mutex> guard(m_child_mutex);
         if (synth_guy->IsSyntheticChildrenGenerated())
diff --git 
a/lldb/test/API/python_api/sbvalue_get_parent/TestSBValueGetParent.py 
b/lldb/test/API/python_api/sbvalue_get_parent/TestSBValueGetParent.py
index f40eddaabfbe0..63086b9546dc2 100644
--- a/lldb/test/API/python_api/sbvalue_get_parent/TestSBValueGetParent.py
+++ b/lldb/test/API/python_api/sbvalue_get_parent/TestSBValueGetParent.py
@@ -3,6 +3,7 @@
 from lldbsuite.test.lldbtest import *
 from lldbsuite.test import lldbutil
 
+from typing import Union
 
 class TestCase(TestBase):
     NO_DEBUG_INFO_TESTCASE = True
@@ -14,17 +15,24 @@ def test(self):
         )
         frame = thread.GetFrameAtIndex(0)
 
-        parent = frame.FindVariable("parent")
+        self._do_test(frame, "parent", "child")
+        self._do_test(frame, "vec", 0)
+
+    def _do_test(
+        self, frame: lldb.SBFrame, parent_name: str, child_key: Union[str, int]
+    ):
+        parent = frame.FindVariable(parent_name)
         self.assertTrue(parent.IsValid())
 
-        child = parent.GetChildMemberWithName("child")
+        if isinstance(child_key, int):
+            child = parent.GetChildAtIndex(child_key)
+        else:
+            assert isinstance(child_key, str)
+            child = parent.GetChildMemberWithName(child_key)
         self.assertTrue(child.IsValid())
 
         # GetParent of child should be the parent struct.
         child_parent = child.GetParent()
         self.assertTrue(child_parent.IsValid())
-        self.assertEqual(child_parent.name, "parent")
+        self.assertEqual(child_parent.name, parent_name)
         self.assertEqual(child_parent.GetID(), parent.GetID())
-
-        # GetParent of a top-level variable should be invalid.
-        self.assertFalse(parent.GetParent().IsValid())
diff --git a/lldb/test/API/python_api/sbvalue_get_parent/main.cpp 
b/lldb/test/API/python_api/sbvalue_get_parent/main.cpp
index 27318ae58f92c..cfb3452a70eb5 100644
--- a/lldb/test/API/python_api/sbvalue_get_parent/main.cpp
+++ b/lldb/test/API/python_api/sbvalue_get_parent/main.cpp
@@ -1,3 +1,5 @@
+#include <vector>
+
 struct Child {
   int x;
 };
@@ -8,5 +10,6 @@ struct Parent {
 
 int main() {
   Parent parent = {{1}};
+  std::vector<int> vec = {10, 20, 30};
   return 0; // break here
 }

>From c7e537dee69e5de236ec41c7016c12bdf49d40ba Mon Sep 17 00:00:00 2001
From: Dave Lee <[email protected]>
Date: Mon, 18 May 2026 17:53:47 -0700
Subject: [PATCH 3/3] formatting

---
 .../API/python_api/sbvalue_get_parent/TestSBValueGetParent.py    | 1 +
 1 file changed, 1 insertion(+)

diff --git 
a/lldb/test/API/python_api/sbvalue_get_parent/TestSBValueGetParent.py 
b/lldb/test/API/python_api/sbvalue_get_parent/TestSBValueGetParent.py
index 63086b9546dc2..50a6b95009208 100644
--- a/lldb/test/API/python_api/sbvalue_get_parent/TestSBValueGetParent.py
+++ b/lldb/test/API/python_api/sbvalue_get_parent/TestSBValueGetParent.py
@@ -5,6 +5,7 @@
 
 from typing import Union
 
+
 class TestCase(TestBase):
     NO_DEBUG_INFO_TESTCASE = True
 

_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to