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

>From 42d68784f790cff9e223f84b60a5da7ee5877830 Mon Sep 17 00:00:00 2001
From: Dave Lee <[email protected]>
Date: Wed, 18 Feb 2026 13:42:38 -0800
Subject: [PATCH 1/2] [lldb] Update the calling convention of
 BytecodeSyntheticChildren

This changes how "self" is constructed, where "self" is the data placed on the 
stack
before calls to `num_children`, `get_child_at_index`, etc.

First, the return value of `init` is saved to its own member, `m_init_results`.
Likewise, the return value of `update` is saved to a separate member,
`m_update_results`.

Calls to both `init` and `update` recieve only the value object on their stack. 
This is
done to simplify implementations of `update`. It makes them more "pure", in 
that the
argument is always a single value (the value object). Previously `update` was 
called
with the value of "self", which was shared between `init` and `update`, and was 
mutated
by `update`.

Lastly, the results of `init` and `update` are concatenated to being the value 
of "self"
when calling other methods.
---
 .../lldb/DataFormatters/TypeSynthetic.h       | 10 ++++++-
 lldb/source/DataFormatters/TypeSynthetic.cpp  | 30 ++++++++++++-------
 2 files changed, 29 insertions(+), 11 deletions(-)

diff --git a/lldb/include/lldb/DataFormatters/TypeSynthetic.h 
b/lldb/include/lldb/DataFormatters/TypeSynthetic.h
index fbf1d060a92b2..ae51ab400ba3d 100644
--- a/lldb/include/lldb/DataFormatters/TypeSynthetic.h
+++ b/lldb/include/lldb/DataFormatters/TypeSynthetic.h
@@ -502,9 +502,17 @@ class BytecodeSyntheticChildren : public SyntheticChildren 
{
     lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override;
     llvm::Expected<size_t> GetIndexOfChildWithName(ConstString name) override;
 
+  private:
+    /// The data stack representing "self". The value of "self" is the results
+    /// of `init` combined with the results of `update`. Together, these values
+    /// are placed on the stack when calling `num_children`,
+    /// `get_child_at_index`, etc.
+    FormatterBytecode::DataStack GetSelf();
+
   private:
     const SyntheticBytecodeImplementation &m_impl;
-    FormatterBytecode::DataStack m_self;
+    FormatterBytecode::DataStack m_init_results;
+    FormatterBytecode::DataStack m_update_results;
   };
 
 public:
diff --git a/lldb/source/DataFormatters/TypeSynthetic.cpp 
b/lldb/source/DataFormatters/TypeSynthetic.cpp
index 10655cdca6f05..6e5721f357c6a 100644
--- a/lldb/source/DataFormatters/TypeSynthetic.cpp
+++ b/lldb/source/DataFormatters/TypeSynthetic.cpp
@@ -20,8 +20,10 @@
 #include "lldb/Symbol/CompilerType.h"
 #include "lldb/Target/Target.h"
 #include "lldb/Utility/StreamString.h"
+#include "llvm/ADT/STLExtras.h"
 #include "llvm/Support/Error.h"
 #include <cstdint>
+#include <iterator>
 
 using namespace lldb;
 using namespace lldb_private;
@@ -258,13 +260,11 @@ std::string ScriptedSyntheticChildren::GetDescription() {
 BytecodeSyntheticChildren::FrontEnd::FrontEnd(
     ValueObject &backend, SyntheticBytecodeImplementation &impl)
     : SyntheticChildrenFrontEnd(backend), m_impl(impl) {
-  FormatterBytecode::DataStack data(backend.GetSP());
-  if (!m_impl.init) {
-    m_self = std::move(data);
+  if (!m_impl.init)
     return;
-  }
 
   FormatterBytecode::ControlStack control = {m_impl.init->getBuffer()};
+  FormatterBytecode::DataStack data = {backend.GetSP()};
   llvm::Error error =
       FormatterBytecode::Interpret(control, data, FormatterBytecode::sig_init);
   if (error) {
@@ -274,7 +274,7 @@ BytecodeSyntheticChildren::FrontEnd::FrontEnd(
   }
 
   if (data.size() > 0)
-    m_self = std::move(data);
+    m_init_results = std::move(data);
 }
 
 lldb::ChildCacheState BytecodeSyntheticChildren::FrontEnd::Update() {
@@ -282,7 +282,7 @@ lldb::ChildCacheState 
BytecodeSyntheticChildren::FrontEnd::Update() {
     return ChildCacheState::eRefetch;
 
   FormatterBytecode::ControlStack control = {m_impl.update->getBuffer()};
-  FormatterBytecode::DataStack data = m_self;
+  FormatterBytecode::DataStack data = {m_backend.GetSP()};
   llvm::Error error = FormatterBytecode::Interpret(
       control, data, FormatterBytecode::sig_update);
   if (error) {
@@ -292,7 +292,7 @@ lldb::ChildCacheState 
BytecodeSyntheticChildren::FrontEnd::Update() {
   }
 
   if (data.size() > 0)
-    m_self = std::move(data);
+    m_update_results = std::move(data);
 
   return ChildCacheState::eRefetch;
 }
@@ -303,7 +303,7 @@ BytecodeSyntheticChildren::FrontEnd::CalculateNumChildren() 
{
     return 0;
 
   FormatterBytecode::ControlStack control = {m_impl.num_children->getBuffer()};
-  FormatterBytecode::DataStack data = m_self;
+  FormatterBytecode::DataStack data = GetSelf();
   llvm::Error error = FormatterBytecode::Interpret(
       control, data, FormatterBytecode::sig_get_num_children);
   if (error)
@@ -335,7 +335,7 @@ 
BytecodeSyntheticChildren::FrontEnd::GetChildAtIndex(uint32_t idx) {
 
   FormatterBytecode::ControlStack control = {
       m_impl.get_child_at_index->getBuffer()};
-  FormatterBytecode::DataStack data = m_self;
+  FormatterBytecode::DataStack data = GetSelf();
   data.emplace_back((uint64_t)idx);
   llvm::Error error = FormatterBytecode::Interpret(
       control, data, FormatterBytecode::sig_get_child_at_index);
@@ -365,7 +365,7 @@ 
BytecodeSyntheticChildren::FrontEnd::GetIndexOfChildWithName(ConstString name) {
 
   FormatterBytecode::ControlStack control = {
       m_impl.get_child_index->getBuffer()};
-  FormatterBytecode::DataStack data = m_self;
+  FormatterBytecode::DataStack data = GetSelf();
   data.emplace_back(name.GetString());
   llvm::Error error = FormatterBytecode::Interpret(
       control, data, FormatterBytecode::sig_get_child_index);
@@ -391,6 +391,16 @@ 
BytecodeSyntheticChildren::FrontEnd::GetIndexOfChildWithName(ConstString name) {
   return llvm::createStringError("@get_child_index returned invalid value");
 }
 
+FormatterBytecode::DataStack BytecodeSyntheticChildren::FrontEnd::GetSelf() {
+  FormatterBytecode::DataStack self;
+  llvm::copy(m_init_results, std::back_inserter(self));
+  llvm::copy(m_update_results, std::back_inserter(self));
+  if (self.empty())
+    // As a fallback, "self" is just the valobj.
+    self.emplace_back(m_backend.GetSP());
+  return self;
+}
+
 std::string BytecodeSyntheticChildren::GetDescription() {
   StreamString sstr;
   sstr.Printf("%s%s%s Bytecode synthetic", Cascades() ? "" : " (not 
cascading)",

>From f339e01b060bda57824072de9783ee2860709111 Mon Sep 17 00:00:00 2001
From: Dave Lee <[email protected]>
Date: Wed, 18 Feb 2026 16:00:53 -0800
Subject: [PATCH 2/2] Update formatterbytecode.rst

---
 lldb/docs/resources/formatterbytecode.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lldb/docs/resources/formatterbytecode.rst 
b/lldb/docs/resources/formatterbytecode.rst
index f6a7b66fa728e..5ceeedab60b99 100644
--- a/lldb/docs/resources/formatterbytecode.rst
+++ b/lldb/docs/resources/formatterbytecode.rst
@@ -223,7 +223,7 @@ Signature    Mnemonic                Stack Effect
   0x03      ``@get_child_index``      ``(Object+ String -> UInt)``
   0x04      ``@get_child_at_index``   ``(Object+ UInt -> Object)``
   0x05      ``@get_value``            ``(Object+ -> String)``
-  0x06      ``@update``               ``(Object+ -> Object+)``
+  0x06      ``@update``               ``(Object -> Object+)``
 =========  ========================= ==============================
 
 If not specified, the init function defaults to an empty function that just 
passes the Object along. Its results may be cached and allow common prep work 
to be done for an Object that can be reused by subsequent calls to the other 
methods. This way subsequent calls to ``@get_child_at_index`` can avoid 
recomputing shared information, for example.

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

Reply via email to