https://github.com/n2h9 created https://github.com/llvm/llvm-project/pull/174847

## Description
Contribution to this topic [Rich Disassembler for 
LLDB](https://discourse.llvm.org/t/rich-disassembler-for-lldb/76952), this part.
```
The rich disassembler output should be exposed as structured data and made 
available through LLDB’s scripting API so more tooling could be built on top of 
this
```

----

This pr adds `SBVariableAnnotator` class for Scripting Bridge API according to 
[the docs](https://lldb.llvm.org/resources/sbapi.html).
`SBVariableAnnotator` is a wrapper for `VariableAnnotator` class from 
Disassembler. 

Details:
- `SBVariableAnnotator` provides single method, `AnnotateStructured` which is a 
wrapper around method with the same name from `VariableAnnotator` class.
- `SBVariableAnnotatorExtensions` adds `get_annotations_list` wrapper around 
`AnnotateStructured` to return annotations list in a "python friendly" way, 
returning annotations as a list of dictionaries. With this structure, client 
can refer to annotation fields by key in a dictionary, without need to call 
methods from `SBStructuredData` class, like `GetItemAtIndex`, `GetBooleanValue` 
etc. 

Original bigger pr for reference:  
https://github.com/llvm/llvm-project/pull/165163

Notes:
- :white_check_mark:  did run black formatter on the python file;

## Testing
Run test with
```sh
./build/bin/lldb-dotest -v -p TestVariableAnnotationsDisassembler.py 
lldb/test/API/functionalities/disassembler-variables
```

all tests (9 existing + 1 newly added) are passing

<details>
<summary>screenshot 2026-01-07</summary>

build from the latest commit  21f7b3b67c05cd38ccf9375fc4ba7ff14842574d

<img width="1327" height="798" alt="image" 
src="https://github.com/user-attachments/assets/72faddd0-0dda-423a-a649-9d9261f5f23f";
 />

</details>
 

>From ee97426b0e0e509be8315e38fe48d752f9db0cb4 Mon Sep 17 00:00:00 2001
From: Nikita B <[email protected]>
Date: Thu, 18 Dec 2025 20:51:43 +0100
Subject: [PATCH 01/29] [lldb] [disassembler] chore: add variable annotator to
 scripting api: add VariableAnnotator to lldb-forward header

Signed-off-by: Nikita B <[email protected]>
---
 lldb/include/lldb/lldb-forward.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lldb/include/lldb/lldb-forward.h b/lldb/include/lldb/lldb-forward.h
index ccfe5efa19e1d..34f756e7bfd48 100644
--- a/lldb/include/lldb/lldb-forward.h
+++ b/lldb/include/lldb/lldb-forward.h
@@ -300,6 +300,7 @@ class ValueObjectConstResultImpl;
 class ValueObjectList;
 class ValueObjectPrinter;
 class Variable;
+class VariableAnnotator;
 class VariableList;
 class Watchpoint;
 class WatchpointList;
@@ -502,6 +503,7 @@ typedef std::shared_ptr<lldb_private::UnwindPlan> 
UnwindPlanSP;
 typedef std::shared_ptr<lldb_private::ValueObject> ValueObjectSP;
 typedef std::shared_ptr<lldb_private::Value> ValueSP;
 typedef std::shared_ptr<lldb_private::Variable> VariableSP;
+typedef std::shared_ptr<lldb_private::VariableAnnotator> VariableAnnotatorSP;
 typedef std::shared_ptr<lldb_private::VariableList> VariableListSP;
 typedef std::shared_ptr<lldb_private::ValueObjectList> ValueObjectListSP;
 typedef std::shared_ptr<lldb_private::Watchpoint> WatchpointSP;

>From 8f617d4151014166e9f93b1f90bee3ead722768e Mon Sep 17 00:00:00 2001
From: Nikita B <[email protected]>
Date: Thu, 18 Dec 2025 23:57:54 +0100
Subject: [PATCH 02/29] [lldb] [disassembler] chore: add variable annotator to
 scripting api: SBVariableAnnotator init

Signed-off-by: Nikita B <[email protected]>
---
 lldb/include/lldb/API/SBVariableAnnotator.h | 32 +++++++++++++++++
 lldb/source/API/SBVariableAnnotator.cpp     | 39 +++++++++++++++++++++
 2 files changed, 71 insertions(+)
 create mode 100644 lldb/include/lldb/API/SBVariableAnnotator.h
 create mode 100644 lldb/source/API/SBVariableAnnotator.cpp

diff --git a/lldb/include/lldb/API/SBVariableAnnotator.h 
b/lldb/include/lldb/API/SBVariableAnnotator.h
new file mode 100644
index 0000000000000..0481d47d4b0c1
--- /dev/null
+++ b/lldb/include/lldb/API/SBVariableAnnotator.h
@@ -0,0 +1,32 @@
+//===-- SBVariableAnnotator.h -----------------------------------------*- C++
+//-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_API_SBVARIABLEANNOTATOR_H
+#define LLDB_API_SBVARIABLEANNOTATOR_H
+
+#include "lldb/API/SBDefines.h"
+
+namespace lldb {
+
+class LLDB_API SBVariableAnnotator {
+public:
+  SBVariableAnnotator();
+
+  SBVariableAnnotator(const SBVariableAnnotator &rhs);
+
+  const SBVariableAnnotator &operator=(const SBVariableAnnotator &rhs);
+
+  ~SBVariableAnnotator();
+
+  explicit operator bool() const;
+
+  bool IsValid() const;
+};
+} // namespace lldb
+#endif // LLDB_API_SBVARIABLEANNOTATOR_H
\ No newline at end of file
diff --git a/lldb/source/API/SBVariableAnnotator.cpp 
b/lldb/source/API/SBVariableAnnotator.cpp
new file mode 100644
index 0000000000000..4d825afa8c84e
--- /dev/null
+++ b/lldb/source/API/SBVariableAnnotator.cpp
@@ -0,0 +1,39 @@
+//===-- SBVariableAnnotator.cpp
+//-------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/API/SBVariableAnnotator.h"
+#include "lldb/Utility/Instrumentation.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+SBVariableAnnotator::SBVariableAnnotator() { LLDB_INSTRUMENT_VA(this); }
+
+SBVariableAnnotator::SBVariableAnnotator(const SBVariableAnnotator &rhs) {
+  LLDB_INSTRUMENT_VA(this);
+}
+
+const SBVariableAnnotator &
+SBVariableAnnotator::operator=(const SBVariableAnnotator &rhs) {
+  LLDB_INSTRUMENT_VA(this);
+
+  //   if (this != &rhs)
+  //     // TODO
+  return *this;
+}
+
+SBVariableAnnotator::~SBVariableAnnotator() = default;
+
+SBVariableAnnotator::operator bool() const {
+  LLDB_INSTRUMENT_VA(this);
+
+  return IsValid();
+}
+
+bool lldb::SBVariableAnnotator::IsValid() const { return false; }

>From 1797af934544fc257b8fcd77a338b7df5cfbf6f1 Mon Sep 17 00:00:00 2001
From: Nikita B <[email protected]>
Date: Fri, 19 Dec 2025 21:16:58 +0100
Subject: [PATCH 03/29] [lldb] [disassembler] chore: add variable annotator to
 scripting api: SBVariableAnnotator: add constructor, getter and setter for
 pointer

Signed-off-by: Nikita B <[email protected]>
---
 lldb/include/lldb/API/SBVariableAnnotator.h | 10 ++++++++++
 lldb/source/API/SBVariableAnnotator.cpp     | 18 ++++++++++++++++++
 2 files changed, 28 insertions(+)

diff --git a/lldb/include/lldb/API/SBVariableAnnotator.h 
b/lldb/include/lldb/API/SBVariableAnnotator.h
index 0481d47d4b0c1..ddce843c134fa 100644
--- a/lldb/include/lldb/API/SBVariableAnnotator.h
+++ b/lldb/include/lldb/API/SBVariableAnnotator.h
@@ -27,6 +27,16 @@ class LLDB_API SBVariableAnnotator {
   explicit operator bool() const;
 
   bool IsValid() const;
+
+protected:
+  SBVariableAnnotator(const lldb::VariableAnnotatorSP &annotator_sp);
+
+  lldb::VariableAnnotatorSP GetSP() const;
+
+  void SetSP(const lldb::VariableAnnotatorSP &annotator_sp);
+
+private:
+  lldb::VariableAnnotatorSP m_opaque_sp;
 };
 } // namespace lldb
 #endif // LLDB_API_SBVARIABLEANNOTATOR_H
\ No newline at end of file
diff --git a/lldb/source/API/SBVariableAnnotator.cpp 
b/lldb/source/API/SBVariableAnnotator.cpp
index 4d825afa8c84e..e5b302a44827d 100644
--- a/lldb/source/API/SBVariableAnnotator.cpp
+++ b/lldb/source/API/SBVariableAnnotator.cpp
@@ -8,6 +8,7 @@
 
//===----------------------------------------------------------------------===//
 
 #include "lldb/API/SBVariableAnnotator.h"
+#include "SBVariableAnnotator.h"
 #include "lldb/Utility/Instrumentation.h"
 
 using namespace lldb;
@@ -37,3 +38,20 @@ SBVariableAnnotator::operator bool() const {
 }
 
 bool lldb::SBVariableAnnotator::IsValid() const { return false; }
+
+lldb::SBVariableAnnotator::SBVariableAnnotator(
+    const lldb::VariableAnnotatorSP &annotator_sp)
+    : m_opaque_sp(annotator_sp) {
+  LLDB_INSTRUMENT_VA(this, annotator_sp);
+}
+
+lldb::VariableAnnotatorSP lldb::SBVariableAnnotator::GetSP() const {
+  LLDB_INSTRUMENT_VA(this);
+  return m_opaque_sp;
+}
+
+void lldb::SBVariableAnnotator::SetSP(
+    const lldb::VariableAnnotatorSP &annotator_sp) {
+  LLDB_INSTRUMENT_VA(this, annotator_sp);
+  m_opaque_sp = annotator_sp;
+}

>From 7d4187117d4f34a8a7260e1303ad7b7624c72fba Mon Sep 17 00:00:00 2001
From: Nikita B <[email protected]>
Date: Tue, 23 Dec 2025 00:31:03 +0100
Subject: [PATCH 04/29] [lldb] [disassembler] chore: add variable annotator to
 scripting api: SBVariableAnnotator: add AnnotateStructured method declaratino
 and implementation stub

---
 lldb/include/lldb/API/SBVariableAnnotator.h | 17 +++++++++++++++++
 lldb/source/API/SBVariableAnnotator.cpp     | 10 ++++++++++
 2 files changed, 27 insertions(+)

diff --git a/lldb/include/lldb/API/SBVariableAnnotator.h 
b/lldb/include/lldb/API/SBVariableAnnotator.h
index ddce843c134fa..ca533b96dabbf 100644
--- a/lldb/include/lldb/API/SBVariableAnnotator.h
+++ b/lldb/include/lldb/API/SBVariableAnnotator.h
@@ -28,6 +28,23 @@ class LLDB_API SBVariableAnnotator {
 
   bool IsValid() const;
 
+  /// Get variable annotations for this instruction as structured data.
+  /// Returns an array of dictionaries, each containing:
+  /// - "variable_name": string name of the variable
+  /// - "location_description": string description of where variable is stored
+  ///   ("RDI", "R15", "undef", etc.)
+  /// - "is_live": boolean indicates if variable is live at this instruction
+  /// - "start_address": unsigned integer address where this annotation becomes
+  ///   valid
+  /// - "end_address": unsigned integer address where this annotation becomes
+  ///   invalid
+  /// - "register_kind": unsigned integer indicating the register numbering
+  /// scheme
+  /// - "decl_file": string path to the file where variable is declared
+  /// - "decl_line": unsigned integer line number where variable is declared
+  /// - "type_name": string type name of the variable
+  lldb::SBStructuredData AnnotateStructured(SBInstruction &inst);
+
 protected:
   SBVariableAnnotator(const lldb::VariableAnnotatorSP &annotator_sp);
 
diff --git a/lldb/source/API/SBVariableAnnotator.cpp 
b/lldb/source/API/SBVariableAnnotator.cpp
index e5b302a44827d..a944b1a7296cd 100644
--- a/lldb/source/API/SBVariableAnnotator.cpp
+++ b/lldb/source/API/SBVariableAnnotator.cpp
@@ -9,6 +9,7 @@
 
 #include "lldb/API/SBVariableAnnotator.h"
 #include "SBVariableAnnotator.h"
+#include "lldb/API/SBStructuredData.h"
 #include "lldb/Utility/Instrumentation.h"
 
 using namespace lldb;
@@ -39,6 +40,15 @@ SBVariableAnnotator::operator bool() const {
 
 bool lldb::SBVariableAnnotator::IsValid() const { return false; }
 
+lldb::SBStructuredData
+lldb::SBVariableAnnotator::AnnotateStructured(SBInstruction &inst) {
+  LLDB_INSTRUMENT_VA(this, inst);
+
+  // TODO: implement
+  lldb::SBStructuredData result;
+  return result;
+}
+
 lldb::SBVariableAnnotator::SBVariableAnnotator(
     const lldb::VariableAnnotatorSP &annotator_sp)
     : m_opaque_sp(annotator_sp) {

>From 6acc07e5dd56722fad612ddb32412af3f4fb7541 Mon Sep 17 00:00:00 2001
From: Nikita B <[email protected]>
Date: Tue, 23 Dec 2025 23:46:52 +0100
Subject: [PATCH 05/29] [lldb] [disassembler] chore: add variable annotator to
 scripting api: SBVariableAnnotator: implement AnnotateStructured method

Signed-off-by: Nikita B <[email protected]>
---
 lldb/include/lldb/API/SBInstruction.h       |  1 +
 lldb/include/lldb/API/SBStructuredData.h    |  1 +
 lldb/include/lldb/API/SBVariableAnnotator.h |  2 +-
 lldb/source/API/SBVariableAnnotator.cpp     | 51 +++++++++++++++++++--
 4 files changed, 51 insertions(+), 4 deletions(-)

diff --git a/lldb/include/lldb/API/SBInstruction.h 
b/lldb/include/lldb/API/SBInstruction.h
index 755e3b4a47c9b..3cd46907c7866 100644
--- a/lldb/include/lldb/API/SBInstruction.h
+++ b/lldb/include/lldb/API/SBInstruction.h
@@ -75,6 +75,7 @@ class LLDB_API SBInstruction {
 
 protected:
   friend class SBInstructionList;
+  friend class SBVariableAnnotator;
 
   SBInstruction(const lldb::DisassemblerSP &disasm_sp,
                 const lldb::InstructionSP &inst_sp);
diff --git a/lldb/include/lldb/API/SBStructuredData.h 
b/lldb/include/lldb/API/SBStructuredData.h
index 05b9ef4cd06f4..4ec30e5113eb1 100644
--- a/lldb/include/lldb/API/SBStructuredData.h
+++ b/lldb/include/lldb/API/SBStructuredData.h
@@ -156,6 +156,7 @@ class SBStructuredData {
   friend class lldb_private::python::SWIGBridge;
   friend class lldb_private::lua::SWIGBridge;
   friend class SBCommandInterpreter;
+  friend class SBVariableAnnotator;
 
   SBStructuredData(const lldb_private::StructuredDataImpl &impl);
 
diff --git a/lldb/include/lldb/API/SBVariableAnnotator.h 
b/lldb/include/lldb/API/SBVariableAnnotator.h
index ca533b96dabbf..bd3cd3b8d5257 100644
--- a/lldb/include/lldb/API/SBVariableAnnotator.h
+++ b/lldb/include/lldb/API/SBVariableAnnotator.h
@@ -43,7 +43,7 @@ class LLDB_API SBVariableAnnotator {
   /// - "decl_file": string path to the file where variable is declared
   /// - "decl_line": unsigned integer line number where variable is declared
   /// - "type_name": string type name of the variable
-  lldb::SBStructuredData AnnotateStructured(SBInstruction &inst);
+  lldb::SBStructuredData AnnotateStructured(SBInstruction inst);
 
 protected:
   SBVariableAnnotator(const lldb::VariableAnnotatorSP &annotator_sp);
diff --git a/lldb/source/API/SBVariableAnnotator.cpp 
b/lldb/source/API/SBVariableAnnotator.cpp
index a944b1a7296cd..53f6ccf418f4d 100644
--- a/lldb/source/API/SBVariableAnnotator.cpp
+++ b/lldb/source/API/SBVariableAnnotator.cpp
@@ -9,7 +9,10 @@
 
 #include "lldb/API/SBVariableAnnotator.h"
 #include "SBVariableAnnotator.h"
+#include "lldb/API/SBInstruction.h"
 #include "lldb/API/SBStructuredData.h"
+#include "lldb/Core/Disassembler.h" // containts VariableAnnotator declaration
+#include "lldb/Core/StructuredDataImpl.h"
 #include "lldb/Utility/Instrumentation.h"
 
 using namespace lldb;
@@ -26,7 +29,7 @@ SBVariableAnnotator::operator=(const SBVariableAnnotator 
&rhs) {
   LLDB_INSTRUMENT_VA(this);
 
   //   if (this != &rhs)
-  //     // TODO
+  //     // TODO implement
   return *this;
 }
 
@@ -38,14 +41,56 @@ SBVariableAnnotator::operator bool() const {
   return IsValid();
 }
 
+// TODO: implement
 bool lldb::SBVariableAnnotator::IsValid() const { return false; }
 
 lldb::SBStructuredData
-lldb::SBVariableAnnotator::AnnotateStructured(SBInstruction &inst) {
+lldb::SBVariableAnnotator::AnnotateStructured(SBInstruction inst) {
   LLDB_INSTRUMENT_VA(this, inst);
 
-  // TODO: implement
   lldb::SBStructuredData result;
+
+  if (lldb::VariableAnnotatorSP annotator_sp = GetSP())
+    if (lldb::InstructionSP inst_sp = inst.GetOpaque()) {
+      auto array_sp = StructuredData::ArraySP();
+
+      const std::vector<lldb_private::VariableAnnotation>
+          structured_annotations = annotator_sp->AnnotateStructured(*inst_sp);
+
+      for (const VariableAnnotation &annotation : structured_annotations) {
+        auto dict_sp = std::make_shared<StructuredData::Dictionary>();
+
+        dict_sp->AddStringItem("variable_name", annotation.variable_name);
+        dict_sp->AddStringItem("location_description",
+                               annotation.location_description);
+        dict_sp->AddBooleanItem("is_live", annotation.is_live);
+        if (annotation.address_range.has_value()) {
+          const auto &range = *annotation.address_range;
+          dict_sp->AddItem("start_address",
+                           std::make_shared<StructuredData::UnsignedInteger>(
+                               range.GetBaseAddress().GetFileAddress()));
+          dict_sp->AddItem("end_address",
+                           std::make_shared<StructuredData::UnsignedInteger>(
+                               range.GetBaseAddress().GetFileAddress() +
+                               range.GetByteSize()));
+        }
+        dict_sp->AddItem("register_kind",
+                         std::make_shared<StructuredData::UnsignedInteger>(
+                             annotation.register_kind));
+        if (annotation.decl_file.has_value())
+          dict_sp->AddStringItem("decl_file", *annotation.decl_file);
+        if (annotation.decl_line.has_value())
+          dict_sp->AddItem("decl_line",
+                           std::make_shared<StructuredData::UnsignedInteger>(
+                               *annotation.decl_line));
+        if (annotation.type_name.has_value())
+          dict_sp->AddStringItem("type_name", *annotation.type_name);
+
+        array_sp->AddItem(dict_sp);
+      }
+
+      result.m_impl_up->SetObjectSP(array_sp);
+    }
   return result;
 }
 

>From 1b33a7b1c6953d46b5232450c350dda40f2427b3 Mon Sep 17 00:00:00 2001
From: Nikita B <[email protected]>
Date: Tue, 23 Dec 2025 23:53:34 +0100
Subject: [PATCH 06/29] [lldb] [disassembler] chore: add variable annotator to
 scripting api: SBVariableAnnotator: implement bool() operator and IsValid
 method

Signed-off-by: Nikita B <[email protected]>
---
 lldb/source/API/SBVariableAnnotator.cpp | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/lldb/source/API/SBVariableAnnotator.cpp 
b/lldb/source/API/SBVariableAnnotator.cpp
index 53f6ccf418f4d..5d7f9ad935b01 100644
--- a/lldb/source/API/SBVariableAnnotator.cpp
+++ b/lldb/source/API/SBVariableAnnotator.cpp
@@ -38,11 +38,13 @@ SBVariableAnnotator::~SBVariableAnnotator() = default;
 SBVariableAnnotator::operator bool() const {
   LLDB_INSTRUMENT_VA(this);
 
-  return IsValid();
+  return m_opaque_sp.get() != nullptr;
 }
 
-// TODO: implement
-bool lldb::SBVariableAnnotator::IsValid() const { return false; }
+bool lldb::SBVariableAnnotator::IsValid() const {
+  LLDB_INSTRUMENT_VA(this);
+  return this->operator bool();
+}
 
 lldb::SBStructuredData
 lldb::SBVariableAnnotator::AnnotateStructured(SBInstruction inst) {

>From 44647bdd08fab24aa7e0ef2f1fb24e33d3b4c2e8 Mon Sep 17 00:00:00 2001
From: Nikita B <[email protected]>
Date: Tue, 23 Dec 2025 23:54:35 +0100
Subject: [PATCH 07/29] [lldb] [disassembler] chore: add variable annotator to
 scripting api: SBVariableAnnotator: implement operator =

Signed-off-by: Nikita B <[email protected]>
---
 lldb/source/API/SBVariableAnnotator.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/lldb/source/API/SBVariableAnnotator.cpp 
b/lldb/source/API/SBVariableAnnotator.cpp
index 5d7f9ad935b01..4e25a09f09837 100644
--- a/lldb/source/API/SBVariableAnnotator.cpp
+++ b/lldb/source/API/SBVariableAnnotator.cpp
@@ -26,10 +26,10 @@ SBVariableAnnotator::SBVariableAnnotator(const 
SBVariableAnnotator &rhs) {
 
 const SBVariableAnnotator &
 SBVariableAnnotator::operator=(const SBVariableAnnotator &rhs) {
-  LLDB_INSTRUMENT_VA(this);
+  LLDB_INSTRUMENT_VA(this, rhs);
 
-  //   if (this != &rhs)
-  //     // TODO implement
+  if (this != &rhs)
+    m_opaque_sp = rhs.m_opaque_sp;
   return *this;
 }
 

>From 6d9a87e7935f71e8a47fb3a5fe34e279f3b52e6d Mon Sep 17 00:00:00 2001
From: Nikita B <[email protected]>
Date: Tue, 23 Dec 2025 23:59:30 +0100
Subject: [PATCH 08/29] [lldb] [disassembler] chore: add variable annotator to
 scripting api: SBVariableAnnotator: implement empty constructor and copy
 constructor

Signed-off-by: Nikita B <[email protected]>
---
 lldb/source/API/SBVariableAnnotator.cpp | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/lldb/source/API/SBVariableAnnotator.cpp 
b/lldb/source/API/SBVariableAnnotator.cpp
index 4e25a09f09837..83723d2042318 100644
--- a/lldb/source/API/SBVariableAnnotator.cpp
+++ b/lldb/source/API/SBVariableAnnotator.cpp
@@ -18,12 +18,15 @@
 using namespace lldb;
 using namespace lldb_private;
 
-SBVariableAnnotator::SBVariableAnnotator() { LLDB_INSTRUMENT_VA(this); }
-
-SBVariableAnnotator::SBVariableAnnotator(const SBVariableAnnotator &rhs) {
+SBVariableAnnotator::SBVariableAnnotator() : m_opaque_sp() {
   LLDB_INSTRUMENT_VA(this);
 }
 
+SBVariableAnnotator::SBVariableAnnotator(const SBVariableAnnotator &rhs)
+    : m_opaque_sp(rhs.m_opaque_sp) {
+  LLDB_INSTRUMENT_VA(this, rhs);
+}
+
 const SBVariableAnnotator &
 SBVariableAnnotator::operator=(const SBVariableAnnotator &rhs) {
   LLDB_INSTRUMENT_VA(this, rhs);

>From dfd559ecb194e1a5a65022713ca139a26a4d24c1 Mon Sep 17 00:00:00 2001
From: Nikita B <[email protected]>
Date: Wed, 24 Dec 2025 00:04:56 +0100
Subject: [PATCH 09/29] [lldb] [disassembler] chore: add variable annotator to
 scripting api: SBVariableAnnotator: drop lldb namespace prefix in front of
 SBVariableAnnotator in implementation file

Signed-off-by: Nikita B <[email protected]>
---
 lldb/source/API/SBVariableAnnotator.cpp | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/lldb/source/API/SBVariableAnnotator.cpp 
b/lldb/source/API/SBVariableAnnotator.cpp
index 83723d2042318..378b70b23bfe9 100644
--- a/lldb/source/API/SBVariableAnnotator.cpp
+++ b/lldb/source/API/SBVariableAnnotator.cpp
@@ -44,13 +44,13 @@ SBVariableAnnotator::operator bool() const {
   return m_opaque_sp.get() != nullptr;
 }
 
-bool lldb::SBVariableAnnotator::IsValid() const {
+bool SBVariableAnnotator::IsValid() const {
   LLDB_INSTRUMENT_VA(this);
   return this->operator bool();
 }
 
 lldb::SBStructuredData
-lldb::SBVariableAnnotator::AnnotateStructured(SBInstruction inst) {
+SBVariableAnnotator::AnnotateStructured(SBInstruction inst) {
   LLDB_INSTRUMENT_VA(this, inst);
 
   lldb::SBStructuredData result;
@@ -99,19 +99,18 @@ lldb::SBVariableAnnotator::AnnotateStructured(SBInstruction 
inst) {
   return result;
 }
 
-lldb::SBVariableAnnotator::SBVariableAnnotator(
+SBVariableAnnotator::SBVariableAnnotator(
     const lldb::VariableAnnotatorSP &annotator_sp)
     : m_opaque_sp(annotator_sp) {
   LLDB_INSTRUMENT_VA(this, annotator_sp);
 }
 
-lldb::VariableAnnotatorSP lldb::SBVariableAnnotator::GetSP() const {
+lldb::VariableAnnotatorSP SBVariableAnnotator::GetSP() const {
   LLDB_INSTRUMENT_VA(this);
   return m_opaque_sp;
 }
 
-void lldb::SBVariableAnnotator::SetSP(
-    const lldb::VariableAnnotatorSP &annotator_sp) {
+void SBVariableAnnotator::SetSP(const lldb::VariableAnnotatorSP &annotator_sp) 
{
   LLDB_INSTRUMENT_VA(this, annotator_sp);
   m_opaque_sp = annotator_sp;
 }

>From ecc2a6dd3e3ced972e646481d9678514d044044e Mon Sep 17 00:00:00 2001
From: Nikita B <[email protected]>
Date: Wed, 24 Dec 2025 00:11:00 +0100
Subject: [PATCH 10/29] [lldb] [disassembler] chore: add variable annotator to
 scripting api: SBVariableAnnotator: include header in LLDB.h

Signed-off-by: Nikita B <[email protected]>
---
 lldb/include/lldb/API/LLDB.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/lldb/include/lldb/API/LLDB.h b/lldb/include/lldb/API/LLDB.h
index 6ac35bb4a364b..f861eb702919e 100644
--- a/lldb/include/lldb/API/LLDB.h
+++ b/lldb/include/lldb/API/LLDB.h
@@ -86,6 +86,7 @@
 #include "lldb/API/SBUnixSignals.h"
 #include "lldb/API/SBValue.h"
 #include "lldb/API/SBValueList.h"
+#include "lldb/API/SBVariableAnnotator.h"
 #include "lldb/API/SBVariablesOptions.h"
 #include "lldb/API/SBWatchpoint.h"
 

>From 3b3fbbcb9c08d0753245ee367a3ce9909628f3f0 Mon Sep 17 00:00:00 2001
From: Nikita B <[email protected]>
Date: Wed, 24 Dec 2025 00:12:24 +0100
Subject: [PATCH 11/29] [lldb] [disassembler] chore: add variable annotator to
 scripting api: SBVariableAnnotator: include header in SBDefines.h

Signed-off-by: Nikita B <[email protected]>
---
 lldb/include/lldb/API/SBDefines.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/lldb/include/lldb/API/SBDefines.h 
b/lldb/include/lldb/API/SBDefines.h
index 5fcc685050c0b..123b4a6de28e9 100644
--- a/lldb/include/lldb/API/SBDefines.h
+++ b/lldb/include/lldb/API/SBDefines.h
@@ -134,6 +134,7 @@ class LLDB_API SBTypeSynthetic;
 class LLDB_API SBTypeList;
 class LLDB_API SBValue;
 class LLDB_API SBValueList;
+class LLDB_API SBVariableAnnotator;
 class LLDB_API SBVariablesOptions;
 class LLDB_API SBWatchpoint;
 class LLDB_API SBWatchpointOptions;
@@ -152,6 +153,6 @@ typedef lldb::CommandReturnObjectCallbackResult 
(*SBCommandPrintCallback)(
 typedef lldb::SBError (*SBPlatformLocateModuleCallback)(
     void *baton, const lldb::SBModuleSpec &module_spec,
     lldb::SBFileSpec &module_file_spec, lldb::SBFileSpec &symbol_file_spec);
-}
+} // namespace lldb
 
 #endif // LLDB_API_SBDEFINES_H

>From ab6ad2b39beb9077512b26a130b1afa04601f0a6 Mon Sep 17 00:00:00 2001
From: Nikita B <[email protected]>
Date: Sat, 27 Dec 2025 13:35:04 +0100
Subject: [PATCH 12/29] [lldb] [disassembler] chore: add variable annotator to
 scripting api: add SBVariableAnnotator.cpp to CMakeLists.txt

Signed-off-by: Nikita B <[email protected]>
---
 lldb/source/API/CMakeLists.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/lldb/source/API/CMakeLists.txt b/lldb/source/API/CMakeLists.txt
index ac47580d60840..e6c31e768b9e2 100644
--- a/lldb/source/API/CMakeLists.txt
+++ b/lldb/source/API/CMakeLists.txt
@@ -119,6 +119,7 @@ add_lldb_library(liblldb SHARED ${option_framework}
   SBUnixSignals.cpp
   SBValue.cpp
   SBValueList.cpp
+  SBVariableAnnotator.cpp
   SBVariablesOptions.cpp
   SBWatchpoint.cpp
   SBWatchpointOptions.cpp

>From 90617f69cef26fe52786a844da7e7dd11a6ca564 Mon Sep 17 00:00:00 2001
From: Nikita B <[email protected]>
Date: Sat, 27 Dec 2025 13:37:04 +0100
Subject: [PATCH 13/29] [lldb] [disassembler] chore: add variable annotator to
 scripting api: add SBVariableAnnotatorExtensions.i

Signed-off-by: Nikita B <[email protected]>
---
 .../interface/SBVariableAnnotatorExtensions.i | 52 +++++++++++++++++++
 1 file changed, 52 insertions(+)
 create mode 100644 lldb/bindings/interface/SBVariableAnnotatorExtensions.i

diff --git a/lldb/bindings/interface/SBVariableAnnotatorExtensions.i 
b/lldb/bindings/interface/SBVariableAnnotatorExtensions.i
new file mode 100644
index 0000000000000..5eb7009ce97e7
--- /dev/null
+++ b/lldb/bindings/interface/SBVariableAnnotatorExtensions.i
@@ -0,0 +1,52 @@
+STRING_EXTENSION_OUTSIDE(SBVariableAnnotator)
+
+    % extend lldb::SBVariableAnnotator {
+#ifdef SWIGPYTHON
+  % pythoncode % {
+        def get_annotations_list(self, instruction):
+            """Get variable annotations as a Python list of dictionaries.
+
+            Args:
+                instruction: SBInstruction object to annotate
+
+            Returns:
+                List of dictionaries, each containing variable annotation data
+            """
+            structured_data = self.AnnotateStructured(instruction)
+            if not structured_data.IsValid():
+                return []
+
+            annotations = []
+            for i in range(structured_data.GetSize()):
+                item = structured_data.GetItemAtIndex(i)
+                if item.GetType() != lldb.eStructuredDataTypeDictionary:
+                    continue
+
+                annotation = {}
+
+                boolean_fields = ['is_live']
+                integer_fields = ['start_address', 'end_address', 
'register_kind', 'decl_line']
+                string_fields = ['variable_name', 'location_description', 
'decl_file', 'type_name']
+
+                for field in boolean_fields:
+                    value = item.GetValueForKey(field)
+                    if value.IsValid():
+                        annotation[field] = value.GetBooleanValue()
+
+                for field in integer_fields:
+                    value = item.GetValueForKey(field)
+                    if value.IsValid():
+                        annotation[field] = value.GetUnsignedIntegerValue()
+
+                for field in string_fields:
+                    value = item.GetValueForKey(field)
+                    if value.IsValid():
+                        annotation[field] = value.GetStringValue(1024)
+
+                annotations.append(annotation)
+
+            return annotations
+    %
+  }
+#endif
+}
\ No newline at end of file

>From 40b5ff04be5728034a264cc18e17f0f73dd510b2 Mon Sep 17 00:00:00 2001
From: Nikita B <[email protected]>
Date: Sat, 27 Dec 2025 13:37:30 +0100
Subject: [PATCH 14/29] [lldb] [disassembler] chore: add variable annotator to
 scripting api: add SBVariableAnnotatorDocstrings.i

Signed-off-by: Nikita B <[email protected]>
---
 .../interface/SBVariableAnnotatorDocstrings.i | 83 +++++++++++++++++++
 1 file changed, 83 insertions(+)
 create mode 100644 lldb/bindings/interface/SBVariableAnnotatorDocstrings.i

diff --git a/lldb/bindings/interface/SBVariableAnnotatorDocstrings.i 
b/lldb/bindings/interface/SBVariableAnnotatorDocstrings.i
new file mode 100644
index 0000000000000..9f3b4c4b514db
--- /dev/null
+++ b/lldb/bindings/interface/SBVariableAnnotatorDocstrings.i
@@ -0,0 +1,83 @@
+%feature("docstring",
+"Provides variable annotation functionality for disassembly instructions.
+
+The SBVariableAnnotator class enables retrieval of structured variable 
+location information for assembly instructions during debugging. This 
+allows tools to understand where variables are stored (registers, memory) 
+at specific instruction addresses, which is essential for debugging 
+optimized code where variables may move between locations.
+
+The annotator extracts DWARF debug information to provide:
+* Variable names and types
+* Current storage location (register name, memory, undefined)
+* Address ranges where the location is valid
+* Source declaration information
+
+For example, when debugging optimized code::
+
+    annotator = lldb.SBVariableAnnotator()
+    target = lldb.debugger.GetSelectedTarget()
+    frame = target.GetProcess().GetSelectedThread().GetSelectedFrame()
+
+    # Get instructions for current function
+    function = frame.GetFunction()
+    instructions = target.ReadInstructions(function.GetStartAddress(),
+                                         function.GetEndAddress())
+
+    # Annotate each instruction
+    for i in range(instructions.GetSize()):
+        inst = instructions.GetInstructionAtIndex(i)
+        annotations = annotator.AnnotateStructured(inst)
+
+        # Process structured annotation data
+        for j in range(annotations.GetSize()):
+            item = annotations.GetItemAtIndex(j)
+            var_name = 
item.GetValueForKey('variable_name').GetStringValue(1024)
+            location = 
item.GetValueForKey('location_description').GetStringValue(1024)
+            is_live = item.GetValueForKey('is_live').GetBooleanValue()
+
+            print(f'Variable {var_name} in {location}, live: {is_live}')"
+) lldb::SBVariableAnnotator;
+
+%feature("docstring", "
+    Create a new variable annotator instance.
+
+    The annotator can be used to extract variable location information
+    from assembly instructions when debugging programs compiled with
+    debug information.")
+lldb::SBVariableAnnotator::SBVariableAnnotator;
+
+%feature("docstring", "
+    Get variable annotations for an instruction as structured data.
+
+    Returns an SBStructuredData object containing an array of dictionaries,
+    where each dictionary represents one variable annotation with the 
following keys:
+
+    * 'variable_name' (string): Name of the variable
+    * 'location_description' (string): Where the variable is stored
+      (register name like 'RDI', 'R15', or 'undef' if not available)
+    * 'is_live' (boolean): Whether the variable is live at this instruction
+    * 'start_address' (integer): Address where this location becomes valid
+    * 'end_address' (integer): Address where this location becomes invalid
+    * 'register_kind' (integer): Register numbering scheme identifier
+    * 'decl_file' (string): Source file where variable is declared (optional)
+    * 'decl_line' (integer): Line number where variable is declared (optional)
+    * 'type_name' (string): Type name of the variable (optional)
+
+    Args:
+        inst: SBInstruction object to annotate
+
+    Returns:
+        SBStructuredData containing variable annotation array, or invalid
+        SBStructuredData if no annotations are available
+
+    Example usage::
+
+        annotations = annotator.AnnotateStructured(instruction)
+        if annotations.IsValid():
+            for i in range(annotations.GetSize()):
+                item = annotations.GetItemAtIndex(i)
+                name = 
item.GetValueForKey('variable_name').GetStringValue(1024)
+                location = 
item.GetValueForKey('location_description').GetStringValue(1024)
+                print(f'{name} -> {location}')")
+lldb::SBVariableAnnotator::AnnotateStructured;
\ No newline at end of file

>From 5849683ce82c84486308c3cb49eed060b5c934f4 Mon Sep 17 00:00:00 2001
From: Nikita B <[email protected]>
Date: Sun, 28 Dec 2025 14:00:20 +0100
Subject: [PATCH 15/29] [lldb] [disassembler] chore: add variable annotator to
 scripting api: fix import in SBVariableAnnotator.cpp

Signed-off-by: Nikita B <[email protected]>
---
 lldb/source/API/SBVariableAnnotator.cpp | 1 -
 1 file changed, 1 deletion(-)

diff --git a/lldb/source/API/SBVariableAnnotator.cpp 
b/lldb/source/API/SBVariableAnnotator.cpp
index 378b70b23bfe9..66b8f93ad6fef 100644
--- a/lldb/source/API/SBVariableAnnotator.cpp
+++ b/lldb/source/API/SBVariableAnnotator.cpp
@@ -8,7 +8,6 @@
 
//===----------------------------------------------------------------------===//
 
 #include "lldb/API/SBVariableAnnotator.h"
-#include "SBVariableAnnotator.h"
 #include "lldb/API/SBInstruction.h"
 #include "lldb/API/SBStructuredData.h"
 #include "lldb/Core/Disassembler.h" // containts VariableAnnotator declaration

>From 11df6536257007499583097cd37484b1750f6d98 Mon Sep 17 00:00:00 2001
From: Nikita B <[email protected]>
Date: Mon, 29 Dec 2025 14:15:01 +0100
Subject: [PATCH 16/29] [lldb] [disassembler] chore: add variable annotator to
 scripting api: include SBVariableAnnotator in interfaces.swig

Signed-off-by: Nikita B <[email protected]>
---
 lldb/bindings/interfaces.swig | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/lldb/bindings/interfaces.swig b/lldb/bindings/interfaces.swig
index fddbedf02e835..11c17970b6a8a 100644
--- a/lldb/bindings/interfaces.swig
+++ b/lldb/bindings/interfaces.swig
@@ -86,6 +86,7 @@
 %include "./interface/SBUnixSignalsDocstrings.i"
 %include "./interface/SBValueDocstrings.i"
 %include "./interface/SBValueListDocstrings.i"
+%include "./interface/SBVariableAnnotatorDocstrings.i"
 %include "./interface/SBVariablesOptionsDocstrings.i"
 %include "./interface/SBWatchpointDocstrings.i"
 %include "./interface/SBWatchpointOptionsDocstrings.i"
@@ -169,6 +170,7 @@
 %include "lldb/API/SBUnixSignals.h"
 %include "lldb/API/SBValue.h"
 %include "lldb/API/SBValueList.h"
+%include "lldb/API/SBVariableAnnotator.h"
 %include "lldb/API/SBVariablesOptions.h"
 %include "lldb/API/SBWatchpoint.h"
 %include "lldb/API/SBWatchpointOptions.h"
@@ -230,4 +232,5 @@
 %include "./interface/SBUnixSignalsExtensions.i"
 %include "./interface/SBValueExtensions.i"
 %include "./interface/SBValueListExtensions.i"
+%include "./interface/SBVariableAnnotatorExtensions.i"
 %include "./interface/SBWatchpointExtensions.i"

>From ec6aadda1764a1ee89a9d69d51d247f28f4d8e43 Mon Sep 17 00:00:00 2001
From: Nikita B <[email protected]>
Date: Mon, 29 Dec 2025 14:16:28 +0100
Subject: [PATCH 17/29] [lldb] [disassembler] chore: add variable annotator to
 scripting api: add GetDescription to SBVaribaleAnnotator class

Signed-off-by: Nikita B <[email protected]>
---
 lldb/include/lldb/API/SBStream.h            | 1 +
 lldb/include/lldb/API/SBVariableAnnotator.h | 2 ++
 lldb/source/API/SBVariableAnnotator.cpp     | 9 +++++++++
 3 files changed, 12 insertions(+)

diff --git a/lldb/include/lldb/API/SBStream.h b/lldb/include/lldb/API/SBStream.h
index 21f9d21e0e717..f336827f3fa65 100644
--- a/lldb/include/lldb/API/SBStream.h
+++ b/lldb/include/lldb/API/SBStream.h
@@ -106,6 +106,7 @@ class LLDB_API SBStream {
   friend class SBTypeMemberFunction;
   friend class SBTypeMember;
   friend class SBValue;
+  friend class SBVariableAnnotator;
   friend class SBWatchpoint;
 
   friend class lldb_private::ScriptInterpreter;
diff --git a/lldb/include/lldb/API/SBVariableAnnotator.h 
b/lldb/include/lldb/API/SBVariableAnnotator.h
index bd3cd3b8d5257..d442e19431109 100644
--- a/lldb/include/lldb/API/SBVariableAnnotator.h
+++ b/lldb/include/lldb/API/SBVariableAnnotator.h
@@ -28,6 +28,8 @@ class LLDB_API SBVariableAnnotator {
 
   bool IsValid() const;
 
+  bool GetDescription(SBStream &description) const;
+
   /// Get variable annotations for this instruction as structured data.
   /// Returns an array of dictionaries, each containing:
   /// - "variable_name": string name of the variable
diff --git a/lldb/source/API/SBVariableAnnotator.cpp 
b/lldb/source/API/SBVariableAnnotator.cpp
index 66b8f93ad6fef..71a5ef56df4e2 100644
--- a/lldb/source/API/SBVariableAnnotator.cpp
+++ b/lldb/source/API/SBVariableAnnotator.cpp
@@ -9,6 +9,7 @@
 
 #include "lldb/API/SBVariableAnnotator.h"
 #include "lldb/API/SBInstruction.h"
+#include "lldb/API/SBStream.h"
 #include "lldb/API/SBStructuredData.h"
 #include "lldb/Core/Disassembler.h" // containts VariableAnnotator declaration
 #include "lldb/Core/StructuredDataImpl.h"
@@ -48,6 +49,14 @@ bool SBVariableAnnotator::IsValid() const {
   return this->operator bool();
 }
 
+bool SBVariableAnnotator::GetDescription(SBStream &description) const {
+  LLDB_INSTRUMENT_VA(this, description);
+
+  Stream &strm = description.ref();
+  strm.Printf("SBVariableAnnotator");
+  return true;
+}
+
 lldb::SBStructuredData
 SBVariableAnnotator::AnnotateStructured(SBInstruction inst) {
   LLDB_INSTRUMENT_VA(this, inst);

>From 635ef109a7d0c6df74d5eb894f1a37a1c72bef47 Mon Sep 17 00:00:00 2001
From: Nikita B <[email protected]>
Date: Mon, 29 Dec 2025 14:23:22 +0100
Subject: [PATCH 18/29] [lldb] [disassembler] chore: add variable annotator to
 scripting api: fix formatting in SBVariableAnnotatorExtensions.i

Signed-off-by: Nikita B <[email protected]>
---
 lldb/bindings/interface/SBVariableAnnotatorExtensions.i | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/lldb/bindings/interface/SBVariableAnnotatorExtensions.i 
b/lldb/bindings/interface/SBVariableAnnotatorExtensions.i
index 5eb7009ce97e7..a0e940e7f17af 100644
--- a/lldb/bindings/interface/SBVariableAnnotatorExtensions.i
+++ b/lldb/bindings/interface/SBVariableAnnotatorExtensions.i
@@ -1,8 +1,8 @@
 STRING_EXTENSION_OUTSIDE(SBVariableAnnotator)
 
-    % extend lldb::SBVariableAnnotator {
+%extend lldb::SBVariableAnnotator {
 #ifdef SWIGPYTHON
-  % pythoncode % {
+  %pythoncode %{
         def get_annotations_list(self, instruction):
             """Get variable annotations as a Python list of dictionaries.
 
@@ -46,7 +46,6 @@ STRING_EXTENSION_OUTSIDE(SBVariableAnnotator)
                 annotations.append(annotation)
 
             return annotations
-    %
-  }
+  %}
 #endif
-}
\ No newline at end of file
+}

>From a18f53179ccf6aef78dfbaf92a20ab2fa199dcb9 Mon Sep 17 00:00:00 2001
From: Nikita B <[email protected]>
Date: Mon, 29 Dec 2025 23:46:21 +0100
Subject: [PATCH 19/29] [lldb] [disassembler] chore: add variable annotator to
 scripting api: copy test_structured_annotations_api from draft pr #165163,
 replace to use new class SBVariableAnnotator

Signed-off-by: Nikita B <[email protected]>
---
 .../TestVariableAnnotationsDisassembler.py    | 100 ++++++++++++++++++
 1 file changed, 100 insertions(+)

diff --git 
a/lldb/test/API/functionalities/disassembler-variables/TestVariableAnnotationsDisassembler.py
 
b/lldb/test/API/functionalities/disassembler-variables/TestVariableAnnotationsDisassembler.py
index f107efbddddeb..b600eed245535 100644
--- 
a/lldb/test/API/functionalities/disassembler-variables/TestVariableAnnotationsDisassembler.py
+++ 
b/lldb/test/API/functionalities/disassembler-variables/TestVariableAnnotationsDisassembler.py
@@ -116,3 +116,103 @@ def test_seed_reg_const_undef(self):
         print(out)
         self.assertRegex(out, r"\b(i|argc)\s*=\s*(DW_OP_reg\d+\b|R[A-Z0-9]+)")
         self.assertNotIn("<decoding error>", out)
+
+    @no_debug_info_test
+    @skipIf(archs=no_match(["x86_64"]))
+    def test_structured_annotations_api(self):
+        """Test SBVariableAnnotator::AnnotateStructured API returns structured 
data"""
+        obj = self._build_obj("d_original_example.o")
+        target = self._create_target(obj)
+        annotator = lldb.SBVariableAnnotator()
+
+        main_symbols = target.FindSymbols("main")
+        self.assertTrue(
+            main_symbols.IsValid() and main_symbols.GetSize() > 0,
+            "Could not find 'main' symbol",
+        )
+
+        main_symbol = main_symbols.GetContextAtIndex(0).GetSymbol()
+        start_addr = main_symbol.GetStartAddress()
+        self.assertTrue(start_addr.IsValid(), "Invalid start address for main")
+
+        instructions = target.ReadInstructions(start_addr, 16)
+        self.assertGreater(instructions.GetSize(), 0, "No instructions read")
+
+        if self.TraceOn():
+            print(
+                f"\nTesting SBVariableAnnotator::AnnotateStructured API on 
{instructions.GetSize()} instructions"
+            )
+
+        expected_vars = ["argc", "argv", "i"]
+        found_variables = set()
+
+        # Test each instruction.
+        for i in range(instructions.GetSize()):
+            inst = instructions.GetInstructionAtIndex(i)
+            self.assertTrue(inst.IsValid(), f"Invalid instruction at index 
{i}")
+
+            # TODO use more python convinient get_annotations_list defined in 
Extensions file.
+            annotations = annotator.AnnotateStructured(inst)
+
+            self.assertIsInstance(
+                annotations,
+                lldb.SBStructuredData,
+                "AnnotateStructured should return SBStructuredData",
+            )
+
+            self.assertTrue(
+                annotations.GetSize() > 0,
+                "AnnotateStructured should return non empty array",
+            )
+
+            if annotations.GetSize() > 0:
+                # Validate each annotation.
+                for j in range(annotations.GetSize()):
+                    ann = annotations.GetItemAtIndex(j)
+                    self.assertTrue(ann.IsValid(), f"Invalid annotation at 
index {j}")
+
+                    self.assertEqual(
+                        ann.GetType(),
+                        lldb.eStructuredDataTypeDictionary,
+                        "Each annotation should be a dictionary",
+                    )
+
+                    var_name_obj = ann.GetValueForKey("variable_name")
+                    self.assertTrue(
+                        var_name_obj.IsValid(), "Missing 'variable_name' field"
+                    )
+
+                    location_obj = ann.GetValueForKey("location_description")
+                    self.assertTrue(
+                        location_obj.IsValid(), "Missing 
'location_description' field"
+                    )
+
+                    is_live_obj = ann.GetValueForKey("is_live")
+                    self.assertTrue(is_live_obj.IsValid(), "Missing 'is_live' 
field")
+
+                    start_addr_obj = ann.GetValueForKey("start_address")
+                    self.assertTrue(
+                        start_addr_obj.IsValid(), "Missing 'start_address' 
field"
+                    )
+
+                    end_addr_obj = ann.GetValueForKey("end_address")
+                    self.assertTrue(
+                        end_addr_obj.IsValid(), "Missing 'end_address' field"
+                    )
+
+                    register_kind_obj = ann.GetValueForKey("register_kind")
+                    self.assertTrue(
+                        register_kind_obj.IsValid(), "Missing 'register_kind' 
field"
+                    )
+
+                    var_name = var_name_obj.GetStringValue(1024)
+
+                    # Check for expected variables in this function.
+                    self.assertIn(
+                        var_name, expected_vars, f"Unexpected variable name: 
{var_name}"
+                    )
+
+                    found_variables.add(var_name)
+
+        if self.TraceOn():
+            print(f"\nTest complete. Found variables: {found_variables}")
\ No newline at end of file

>From 44b4581c80acab477ae04f3bfba47b468751b9e0 Mon Sep 17 00:00:00 2001
From: Nikita B <[email protected]>
Date: Wed, 31 Dec 2025 00:16:06 +0100
Subject: [PATCH 20/29] [lldb] [disassembler] chore: add variable annotator to
 scripting api: instantiate opaque pointer in default constructor; properly
 instantiate structured data array

Signed-off-by: Nikita B <[email protected]>
---
 lldb/source/API/SBVariableAnnotator.cpp | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/lldb/source/API/SBVariableAnnotator.cpp 
b/lldb/source/API/SBVariableAnnotator.cpp
index 71a5ef56df4e2..c59423c771aa3 100644
--- a/lldb/source/API/SBVariableAnnotator.cpp
+++ b/lldb/source/API/SBVariableAnnotator.cpp
@@ -18,7 +18,8 @@
 using namespace lldb;
 using namespace lldb_private;
 
-SBVariableAnnotator::SBVariableAnnotator() : m_opaque_sp() {
+SBVariableAnnotator::SBVariableAnnotator()
+    : m_opaque_sp(std::make_shared<VariableAnnotator>()) {
   LLDB_INSTRUMENT_VA(this);
 }
 
@@ -65,7 +66,8 @@ SBVariableAnnotator::AnnotateStructured(SBInstruction inst) {
 
   if (lldb::VariableAnnotatorSP annotator_sp = GetSP())
     if (lldb::InstructionSP inst_sp = inst.GetOpaque()) {
-      auto array_sp = StructuredData::ArraySP();
+      StructuredData::ArraySP array_sp =
+          std::make_shared<StructuredData::Array>();
 
       const std::vector<lldb_private::VariableAnnotation>
           structured_annotations = annotator_sp->AnnotateStructured(*inst_sp);

>From 11f004618c99e1913e653274e1b445f2bc474945 Mon Sep 17 00:00:00 2001
From: Nikita B <[email protected]>
Date: Wed, 31 Dec 2025 00:16:51 +0100
Subject: [PATCH 21/29] [lldb] [disassembler] chore: add variable annotator to
 scripting api: fix typo in comment

Signed-off-by: Nikita B <[email protected]>
---
 lldb/source/API/SBVariableAnnotator.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lldb/source/API/SBVariableAnnotator.cpp 
b/lldb/source/API/SBVariableAnnotator.cpp
index c59423c771aa3..a6fdddb795011 100644
--- a/lldb/source/API/SBVariableAnnotator.cpp
+++ b/lldb/source/API/SBVariableAnnotator.cpp
@@ -11,7 +11,7 @@
 #include "lldb/API/SBInstruction.h"
 #include "lldb/API/SBStream.h"
 #include "lldb/API/SBStructuredData.h"
-#include "lldb/Core/Disassembler.h" // containts VariableAnnotator declaration
+#include "lldb/Core/Disassembler.h" // contains VariableAnnotator declaration
 #include "lldb/Core/StructuredDataImpl.h"
 #include "lldb/Utility/Instrumentation.h"
 

>From 17ba027703e3dca6cdbb072081142f6025d2c29a Mon Sep 17 00:00:00 2001
From: Nikita B <[email protected]>
Date: Thu, 1 Jan 2026 14:31:06 +0100
Subject: [PATCH 22/29] [lldb] [disassembler] chore: add variable annotator to
 scripting api: update test to use annotator created once

Signed-off-by: Nikita B <[email protected]>
---
 .../TestVariableAnnotationsDisassembler.py    | 138 +++++++++++-------
 1 file changed, 82 insertions(+), 56 deletions(-)

diff --git 
a/lldb/test/API/functionalities/disassembler-variables/TestVariableAnnotationsDisassembler.py
 
b/lldb/test/API/functionalities/disassembler-variables/TestVariableAnnotationsDisassembler.py
index b600eed245535..c894d0e2559de 100644
--- 
a/lldb/test/API/functionalities/disassembler-variables/TestVariableAnnotationsDisassembler.py
+++ 
b/lldb/test/API/functionalities/disassembler-variables/TestVariableAnnotationsDisassembler.py
@@ -123,7 +123,6 @@ def test_structured_annotations_api(self):
         """Test SBVariableAnnotator::AnnotateStructured API returns structured 
data"""
         obj = self._build_obj("d_original_example.o")
         target = self._create_target(obj)
-        annotator = lldb.SBVariableAnnotator()
 
         main_symbols = target.FindSymbols("main")
         self.assertTrue(
@@ -144,6 +143,11 @@ def test_structured_annotations_api(self):
             )
 
         expected_vars = ["argc", "argv", "i"]
+
+        annotator = lldb.SBVariableAnnotator()
+
+        # Track current state of variables across instructions.
+        active_vars = {}  # var_name -> location_description.
         found_variables = set()
 
         # Test each instruction.
@@ -151,7 +155,8 @@ def test_structured_annotations_api(self):
             inst = instructions.GetInstructionAtIndex(i)
             self.assertTrue(inst.IsValid(), f"Invalid instruction at index 
{i}")
 
-            # TODO use more python convinient get_annotations_list defined in 
Extensions file.
+            # TODO: use get_annotations_list from Extensions.i.
+            # Get annotations (may be empty if nothing changed).
             annotations = annotator.AnnotateStructured(inst)
 
             self.assertIsInstance(
@@ -160,59 +165,80 @@ def test_structured_annotations_api(self):
                 "AnnotateStructured should return SBStructuredData",
             )
 
-            self.assertTrue(
-                annotations.GetSize() > 0,
-                "AnnotateStructured should return non empty array",
-            )
-
-            if annotations.GetSize() > 0:
-                # Validate each annotation.
-                for j in range(annotations.GetSize()):
-                    ann = annotations.GetItemAtIndex(j)
-                    self.assertTrue(ann.IsValid(), f"Invalid annotation at 
index {j}")
-
-                    self.assertEqual(
-                        ann.GetType(),
-                        lldb.eStructuredDataTypeDictionary,
-                        "Each annotation should be a dictionary",
-                    )
-
-                    var_name_obj = ann.GetValueForKey("variable_name")
-                    self.assertTrue(
-                        var_name_obj.IsValid(), "Missing 'variable_name' field"
-                    )
-
-                    location_obj = ann.GetValueForKey("location_description")
-                    self.assertTrue(
-                        location_obj.IsValid(), "Missing 
'location_description' field"
-                    )
-
-                    is_live_obj = ann.GetValueForKey("is_live")
-                    self.assertTrue(is_live_obj.IsValid(), "Missing 'is_live' 
field")
-
-                    start_addr_obj = ann.GetValueForKey("start_address")
-                    self.assertTrue(
-                        start_addr_obj.IsValid(), "Missing 'start_address' 
field"
-                    )
-
-                    end_addr_obj = ann.GetValueForKey("end_address")
-                    self.assertTrue(
-                        end_addr_obj.IsValid(), "Missing 'end_address' field"
-                    )
-
-                    register_kind_obj = ann.GetValueForKey("register_kind")
-                    self.assertTrue(
-                        register_kind_obj.IsValid(), "Missing 'register_kind' 
field"
-                    )
-
-                    var_name = var_name_obj.GetStringValue(1024)
-
-                    # Check for expected variables in this function.
-                    self.assertIn(
-                        var_name, expected_vars, f"Unexpected variable name: 
{var_name}"
-                    )
-
-                    found_variables.add(var_name)
+            # Process changes.
+            for j in range(annotations.GetSize()):
+                ann = annotations.GetItemAtIndex(j)
+                self.assertTrue(ann.IsValid(), f"Invalid annotation at index 
{j}")
+
+                self.assertEqual(
+                    ann.GetType(),
+                    lldb.eStructuredDataTypeDictionary,
+                    "Each annotation should be a dictionary",
+                )
+
+                # Validate all required fields are present.
+                var_name_obj = ann.GetValueForKey("variable_name")
+                self.assertTrue(
+                    var_name_obj.IsValid(), "Missing 'variable_name' field"
+                )
+
+                location_obj = ann.GetValueForKey("location_description")
+                self.assertTrue(
+                    location_obj.IsValid(), "Missing 'location_description' 
field"
+                )
+
+                is_live_obj = ann.GetValueForKey("is_live")
+                self.assertTrue(is_live_obj.IsValid(), "Missing 'is_live' 
field")
+
+                start_addr_obj = ann.GetValueForKey("start_address")
+                self.assertTrue(
+                    start_addr_obj.IsValid(), "Missing 'start_address' field"
+                )
+
+                end_addr_obj = ann.GetValueForKey("end_address")
+                self.assertTrue(
+                    end_addr_obj.IsValid(), "Missing 'end_address' field"
+                )
+
+                register_kind_obj = ann.GetValueForKey("register_kind")
+                self.assertTrue(
+                    register_kind_obj.IsValid(), "Missing 'register_kind' 
field"
+                )
+
+                var_name = var_name_obj.GetStringValue(1024)
+                location = location_obj.GetStringValue(1024)
+                is_live = is_live_obj.GetBooleanValue()
+
+                self.assertIn(
+                    var_name, expected_vars, f"Unexpected variable name: 
{var_name}"
+                )
+
+                found_variables.add(var_name)
+
+                # Update tracking state.
+                if location == "undef" or not is_live:
+                    # Variable went away.
+                    if var_name in active_vars:
+                        if self.TraceOn():
+                            print(f"  [{i:2d}] {var_name}: 
{active_vars[var_name]} -> undef")
+                        active_vars.pop(var_name)
+                else:
+                    # Variable newly live or location changed.
+                    old_location = active_vars.get(var_name)
+                    if old_location != location:
+                        if self.TraceOn():
+                            if old_location is None:
+                                print(f"  [{i:2d}] {var_name}: -> {location} 
(newly live)")
+                            else:
+                                print(f"  [{i:2d}] {var_name}: {old_location} 
-> {location} (changed)")
+                        active_vars[var_name] = location
+
+        # Validate we find all expected variables.
+        self.assertEqual(
+            found_variables,
+            set(expected_vars),
+            f"Did not find all expected variables. Expected: {expected_vars}, 
find: {found_variables}"
+        )
 
         if self.TraceOn():
-            print(f"\nTest complete. Found variables: {found_variables}")
\ No newline at end of file
+            print(f"\nTest complete. All expected variables found: 
{found_variables}")

>From c57962de6f46ca45ee8604a6e82a90652d2b2f5d Mon Sep 17 00:00:00 2001
From: Nikita B <[email protected]>
Date: Tue, 6 Jan 2026 18:52:07 +0100
Subject: [PATCH 23/29] [lldb] [disassembler] chore: add variable annotator to
 scripting api: remove unused protected methods

Signed-off-by: Nikita B <[email protected]>
---
 lldb/include/lldb/API/SBVariableAnnotator.h | 7 -------
 lldb/source/API/SBVariableAnnotator.cpp     | 4 ++--
 2 files changed, 2 insertions(+), 9 deletions(-)

diff --git a/lldb/include/lldb/API/SBVariableAnnotator.h 
b/lldb/include/lldb/API/SBVariableAnnotator.h
index d442e19431109..14563e3256ea6 100644
--- a/lldb/include/lldb/API/SBVariableAnnotator.h
+++ b/lldb/include/lldb/API/SBVariableAnnotator.h
@@ -47,13 +47,6 @@ class LLDB_API SBVariableAnnotator {
   /// - "type_name": string type name of the variable
   lldb::SBStructuredData AnnotateStructured(SBInstruction inst);
 
-protected:
-  SBVariableAnnotator(const lldb::VariableAnnotatorSP &annotator_sp);
-
-  lldb::VariableAnnotatorSP GetSP() const;
-
-  void SetSP(const lldb::VariableAnnotatorSP &annotator_sp);
-
 private:
   lldb::VariableAnnotatorSP m_opaque_sp;
 };
diff --git a/lldb/source/API/SBVariableAnnotator.cpp 
b/lldb/source/API/SBVariableAnnotator.cpp
index a6fdddb795011..1df8c11fef181 100644
--- a/lldb/source/API/SBVariableAnnotator.cpp
+++ b/lldb/source/API/SBVariableAnnotator.cpp
@@ -64,13 +64,13 @@ SBVariableAnnotator::AnnotateStructured(SBInstruction inst) 
{
 
   lldb::SBStructuredData result;
 
-  if (lldb::VariableAnnotatorSP annotator_sp = GetSP())
+  if (m_opaque_sp)
     if (lldb::InstructionSP inst_sp = inst.GetOpaque()) {
       StructuredData::ArraySP array_sp =
           std::make_shared<StructuredData::Array>();
 
       const std::vector<lldb_private::VariableAnnotation>
-          structured_annotations = annotator_sp->AnnotateStructured(*inst_sp);
+          structured_annotations = m_opaque_sp->AnnotateStructured(*inst_sp);
 
       for (const VariableAnnotation &annotation : structured_annotations) {
         auto dict_sp = std::make_shared<StructuredData::Dictionary>();

>From b922dedfd1b81863deb3260420e6eb988e55535d Mon Sep 17 00:00:00 2001
From: Nikita B <[email protected]>
Date: Tue, 6 Jan 2026 19:08:09 +0100
Subject: [PATCH 24/29] [lldb] [disassembler] chore: add variable annotator to
 scripting api: remove unused protected methods

Signed-off-by: Nikita B <[email protected]>
---
 lldb/source/API/SBVariableAnnotator.cpp | 16 ----------------
 1 file changed, 16 deletions(-)

diff --git a/lldb/source/API/SBVariableAnnotator.cpp 
b/lldb/source/API/SBVariableAnnotator.cpp
index 1df8c11fef181..06d33e2ceb8b3 100644
--- a/lldb/source/API/SBVariableAnnotator.cpp
+++ b/lldb/source/API/SBVariableAnnotator.cpp
@@ -108,19 +108,3 @@ SBVariableAnnotator::AnnotateStructured(SBInstruction 
inst) {
     }
   return result;
 }
-
-SBVariableAnnotator::SBVariableAnnotator(
-    const lldb::VariableAnnotatorSP &annotator_sp)
-    : m_opaque_sp(annotator_sp) {
-  LLDB_INSTRUMENT_VA(this, annotator_sp);
-}
-
-lldb::VariableAnnotatorSP SBVariableAnnotator::GetSP() const {
-  LLDB_INSTRUMENT_VA(this);
-  return m_opaque_sp;
-}
-
-void SBVariableAnnotator::SetSP(const lldb::VariableAnnotatorSP &annotator_sp) 
{
-  LLDB_INSTRUMENT_VA(this, annotator_sp);
-  m_opaque_sp = annotator_sp;
-}

>From fd5befc36270a5b300a8bee72ad11d5a7a48ffe3 Mon Sep 17 00:00:00 2001
From: Nikita B <[email protected]>
Date: Tue, 6 Jan 2026 19:23:35 +0100
Subject: [PATCH 25/29] [lldb] [disassembler] chore: add variable annotator to
 scripting api: some minor updates to Docstrings.i description

Signed-off-by: Nikita B <[email protected]>
---
 .../interface/SBVariableAnnotatorDocstrings.i    | 16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/lldb/bindings/interface/SBVariableAnnotatorDocstrings.i 
b/lldb/bindings/interface/SBVariableAnnotatorDocstrings.i
index 9f3b4c4b514db..2bc5a07e2cd83 100644
--- a/lldb/bindings/interface/SBVariableAnnotatorDocstrings.i
+++ b/lldb/bindings/interface/SBVariableAnnotatorDocstrings.i
@@ -3,9 +3,8 @@
 
 The SBVariableAnnotator class enables retrieval of structured variable 
 location information for assembly instructions during debugging. This 
-allows tools to understand where variables are stored (registers, memory) 
-at specific instruction addresses, which is essential for debugging 
-optimized code where variables may move between locations.
+allows to understand where variables are stored (registers, memory) 
+at specific instruction addresses.
 
 The annotator extracts DWARF debug information to provide:
 * Variable names and types
@@ -13,30 +12,29 @@ The annotator extracts DWARF debug information to provide:
 * Address ranges where the location is valid
 * Source declaration information
 
-For example, when debugging optimized code::
+For example, when debugging optimized code:
 
     annotator = lldb.SBVariableAnnotator()
     target = lldb.debugger.GetSelectedTarget()
     frame = target.GetProcess().GetSelectedThread().GetSelectedFrame()
 
-    # Get instructions for current function
+    # Get instructions for current function.
     function = frame.GetFunction()
     instructions = target.ReadInstructions(function.GetStartAddress(),
                                          function.GetEndAddress())
 
-    # Annotate each instruction
+    # Annotate each instruction.
     for i in range(instructions.GetSize()):
         inst = instructions.GetInstructionAtIndex(i)
         annotations = annotator.AnnotateStructured(inst)
 
-        # Process structured annotation data
+        # Process structured annotation data.
         for j in range(annotations.GetSize()):
             item = annotations.GetItemAtIndex(j)
             var_name = 
item.GetValueForKey('variable_name').GetStringValue(1024)
             location = 
item.GetValueForKey('location_description').GetStringValue(1024)
-            is_live = item.GetValueForKey('is_live').GetBooleanValue()
 
-            print(f'Variable {var_name} in {location}, live: {is_live}')"
+            print(f'Variable {var_name} in {location}')"
 ) lldb::SBVariableAnnotator;
 
 %feature("docstring", "

>From 8ddc09c04b690d94562fa91769974330d6208d21 Mon Sep 17 00:00:00 2001
From: Nikita B <[email protected]>
Date: Tue, 6 Jan 2026 20:50:06 +0100
Subject: [PATCH 26/29] [lldb] [disassembler] chore: add variable annotator to
 scripting api: remove lldb from Extensions.i

Signed-off-by: Nikita B <[email protected]>
---
 lldb/bindings/interface/SBVariableAnnotatorExtensions.i | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lldb/bindings/interface/SBVariableAnnotatorExtensions.i 
b/lldb/bindings/interface/SBVariableAnnotatorExtensions.i
index a0e940e7f17af..582be364ec14b 100644
--- a/lldb/bindings/interface/SBVariableAnnotatorExtensions.i
+++ b/lldb/bindings/interface/SBVariableAnnotatorExtensions.i
@@ -19,7 +19,7 @@ STRING_EXTENSION_OUTSIDE(SBVariableAnnotator)
             annotations = []
             for i in range(structured_data.GetSize()):
                 item = structured_data.GetItemAtIndex(i)
-                if item.GetType() != lldb.eStructuredDataTypeDictionary:
+                if item.GetType() != eStructuredDataTypeDictionary:
                     continue
 
                 annotation = {}

>From 9c270c4bf693375084a4545b41f3cee9b45d40ab Mon Sep 17 00:00:00 2001
From: Nikita B <[email protected]>
Date: Tue, 6 Jan 2026 20:57:04 +0100
Subject: [PATCH 27/29] [lldb] [disassembler] chore: add variable annotator to
 scripting api: update test to use get_annotations_list python friendly
 wrapper

Signed-off-by: Nikita B <[email protected]>
---
 .../TestVariableAnnotationsDisassembler.py    | 93 +++++--------------
 1 file changed, 23 insertions(+), 70 deletions(-)

diff --git 
a/lldb/test/API/functionalities/disassembler-variables/TestVariableAnnotationsDisassembler.py
 
b/lldb/test/API/functionalities/disassembler-variables/TestVariableAnnotationsDisassembler.py
index c894d0e2559de..0def625f4b4d9 100644
--- 
a/lldb/test/API/functionalities/disassembler-variables/TestVariableAnnotationsDisassembler.py
+++ 
b/lldb/test/API/functionalities/disassembler-variables/TestVariableAnnotationsDisassembler.py
@@ -120,7 +120,7 @@ def test_seed_reg_const_undef(self):
     @no_debug_info_test
     @skipIf(archs=no_match(["x86_64"]))
     def test_structured_annotations_api(self):
-        """Test SBVariableAnnotator::AnnotateStructured API returns structured 
data"""
+        """Test SBVariableAnnotator.get_annotations_list() Python API."""
         obj = self._build_obj("d_original_example.o")
         target = self._create_target(obj)
 
@@ -139,7 +139,7 @@ def test_structured_annotations_api(self):
 
         if self.TraceOn():
             print(
-                f"\nTesting SBVariableAnnotator::AnnotateStructured API on 
{instructions.GetSize()} instructions"
+                f"\nTesting SBVariableAnnotator.get_annotations_list() on 
{instructions.GetSize()} instructions"
             )
 
         expected_vars = ["argc", "argv", "i"]
@@ -147,7 +147,6 @@ def test_structured_annotations_api(self):
         annotator = lldb.SBVariableAnnotator()
 
         # Track current state of variables across instructions.
-        active_vars = {}  # var_name -> location_description.
         found_variables = set()
 
         # Test each instruction.
@@ -155,59 +154,31 @@ def test_structured_annotations_api(self):
             inst = instructions.GetInstructionAtIndex(i)
             self.assertTrue(inst.IsValid(), f"Invalid instruction at index 
{i}")
 
-            # TODO: use get_annotations_list from Extensions.i.
-            # Get annotations (may be empty if nothing changed).
-            annotations = annotator.AnnotateStructured(inst)
+            # Get annotations as Python list of dicts (may be empty if nothing 
changed).
+            annotations = annotator.get_annotations_list(inst)
 
-            self.assertIsInstance(
-                annotations,
-                lldb.SBStructuredData,
-                "AnnotateStructured should return SBStructuredData",
-            )
-
-            # Process changes.
-            for j in range(annotations.GetSize()):
-                ann = annotations.GetItemAtIndex(j)
-                self.assertTrue(ann.IsValid(), f"Invalid annotation at index 
{j}")
-
-                self.assertEqual(
-                    ann.GetType(),
-                    lldb.eStructuredDataTypeDictionary,
-                    "Each annotation should be a dictionary",
-                )
-
-                # Validate all required fields are present.
-                var_name_obj = ann.GetValueForKey("variable_name")
-                self.assertTrue(
-                    var_name_obj.IsValid(), "Missing 'variable_name' field"
-                )
-
-                location_obj = ann.GetValueForKey("location_description")
-                self.assertTrue(
-                    location_obj.IsValid(), "Missing 'location_description' 
field"
-                )
+            for ann in annotations:
+                # Validate required fields are present.
+                self.assertIn("variable_name", ann, "Missing 'variable_name' 
field")
+                self.assertIn("location_description", ann, "Missing 
'location_description' field")
+                self.assertIn("is_live", ann, "Missing 'is_live' field")
+                self.assertIn("start_address", ann, "Missing 'start_address' 
field")
+                self.assertIn("end_address", ann, "Missing 'end_address' 
field")
+                self.assertIn("register_kind", ann, "Missing 'register_kind' 
field")
 
-                is_live_obj = ann.GetValueForKey("is_live")
-                self.assertTrue(is_live_obj.IsValid(), "Missing 'is_live' 
field")
+                var_name = ann["variable_name"]
 
-                start_addr_obj = ann.GetValueForKey("start_address")
-                self.assertTrue(
-                    start_addr_obj.IsValid(), "Missing 'start_address' field"
-                )
+                # Validate types and values.
+                self.assertIsInstance(var_name, str, "variable_name should be 
string")
+                self.assertIsInstance(ann["location_description"], str, 
"location_description should be string")
+                self.assertIsInstance(ann["is_live"], bool, "is_live should be 
boolean")
+                self.assertIsInstance(ann["start_address"], int, 
"start_address should be integer")
+                self.assertIsInstance(ann["end_address"], int, "end_address 
should be integer")
+                self.assertIsInstance(ann["register_kind"], int, 
"register_kind should be integer")
 
-                end_addr_obj = ann.GetValueForKey("end_address")
-                self.assertTrue(
-                    end_addr_obj.IsValid(), "Missing 'end_address' field"
-                )
-
-                register_kind_obj = ann.GetValueForKey("register_kind")
-                self.assertTrue(
-                    register_kind_obj.IsValid(), "Missing 'register_kind' 
field"
-                )
-
-                var_name = var_name_obj.GetStringValue(1024)
-                location = location_obj.GetStringValue(1024)
-                is_live = is_live_obj.GetBooleanValue()
+                self.assertGreater(len(var_name), 0, "variable_name should not 
be empty")
+                self.assertGreater(len(ann["location_description"]), 0, 
"location_description should not be empty")
+                self.assertGreater(ann["end_address"], ann["start_address"], 
"end_address should be > start_address")
 
                 self.assertIn(
                     var_name, expected_vars, f"Unexpected variable name: 
{var_name}"
@@ -215,24 +186,6 @@ def test_structured_annotations_api(self):
 
                 found_variables.add(var_name)
 
-                # Update tracking state.
-                if location == "undef" or not is_live:
-                    # Variable went away.
-                    if var_name in active_vars:
-                        if self.TraceOn():
-                            print(f"  [{i:2d}] {var_name}: 
{active_vars[var_name]} -> undef")
-                        active_vars.pop(var_name)
-                else:
-                    # Variable newly live or location changed.
-                    old_location = active_vars.get(var_name)
-                    if old_location != location:
-                        if self.TraceOn():
-                            if old_location is None:
-                                print(f"  [{i:2d}] {var_name}: -> {location} 
(newly live)")
-                            else:
-                                print(f"  [{i:2d}] {var_name}: {old_location} 
-> {location} (changed)")
-                        active_vars[var_name] = location
-
         # Validate we find all expected variables.
         self.assertEqual(
             found_variables,

>From dc09acc9197b1fd57b6aae5e7509404c68732070 Mon Sep 17 00:00:00 2001
From: Nikita B <[email protected]>
Date: Tue, 6 Jan 2026 21:12:42 +0100
Subject: [PATCH 28/29] [lldb] [disassembler] chore: add variable annotator to
 scripting api: black formatting

Signed-off-by: Nikita B <[email protected]>
---
 .../TestVariableAnnotationsDisassembler.py    | 40 ++++++++++++++-----
 1 file changed, 31 insertions(+), 9 deletions(-)

diff --git 
a/lldb/test/API/functionalities/disassembler-variables/TestVariableAnnotationsDisassembler.py
 
b/lldb/test/API/functionalities/disassembler-variables/TestVariableAnnotationsDisassembler.py
index 0def625f4b4d9..19889fbbe0bef 100644
--- 
a/lldb/test/API/functionalities/disassembler-variables/TestVariableAnnotationsDisassembler.py
+++ 
b/lldb/test/API/functionalities/disassembler-variables/TestVariableAnnotationsDisassembler.py
@@ -160,7 +160,9 @@ def test_structured_annotations_api(self):
             for ann in annotations:
                 # Validate required fields are present.
                 self.assertIn("variable_name", ann, "Missing 'variable_name' 
field")
-                self.assertIn("location_description", ann, "Missing 
'location_description' field")
+                self.assertIn(
+                    "location_description", ann, "Missing 
'location_description' field"
+                )
                 self.assertIn("is_live", ann, "Missing 'is_live' field")
                 self.assertIn("start_address", ann, "Missing 'start_address' 
field")
                 self.assertIn("end_address", ann, "Missing 'end_address' 
field")
@@ -170,15 +172,35 @@ def test_structured_annotations_api(self):
 
                 # Validate types and values.
                 self.assertIsInstance(var_name, str, "variable_name should be 
string")
-                self.assertIsInstance(ann["location_description"], str, 
"location_description should be string")
+                self.assertIsInstance(
+                    ann["location_description"],
+                    str,
+                    "location_description should be string",
+                )
                 self.assertIsInstance(ann["is_live"], bool, "is_live should be 
boolean")
-                self.assertIsInstance(ann["start_address"], int, 
"start_address should be integer")
-                self.assertIsInstance(ann["end_address"], int, "end_address 
should be integer")
-                self.assertIsInstance(ann["register_kind"], int, 
"register_kind should be integer")
+                self.assertIsInstance(
+                    ann["start_address"], int, "start_address should be 
integer"
+                )
+                self.assertIsInstance(
+                    ann["end_address"], int, "end_address should be integer"
+                )
+                self.assertIsInstance(
+                    ann["register_kind"], int, "register_kind should be 
integer"
+                )
 
-                self.assertGreater(len(var_name), 0, "variable_name should not 
be empty")
-                self.assertGreater(len(ann["location_description"]), 0, 
"location_description should not be empty")
-                self.assertGreater(ann["end_address"], ann["start_address"], 
"end_address should be > start_address")
+                self.assertGreater(
+                    len(var_name), 0, "variable_name should not be empty"
+                )
+                self.assertGreater(
+                    len(ann["location_description"]),
+                    0,
+                    "location_description should not be empty",
+                )
+                self.assertGreater(
+                    ann["end_address"],
+                    ann["start_address"],
+                    "end_address should be > start_address",
+                )
 
                 self.assertIn(
                     var_name, expected_vars, f"Unexpected variable name: 
{var_name}"
@@ -190,7 +212,7 @@ def test_structured_annotations_api(self):
         self.assertEqual(
             found_variables,
             set(expected_vars),
-            f"Did not find all expected variables. Expected: {expected_vars}, 
find: {found_variables}"
+            f"Did not find all expected variables. Expected: {expected_vars}, 
find: {found_variables}",
         )
 
         if self.TraceOn():

>From 21f7b3b67c05cd38ccf9375fc4ba7ff14842574d Mon Sep 17 00:00:00 2001
From: Nikita B <[email protected]>
Date: Wed, 7 Jan 2026 18:55:27 +0100
Subject: [PATCH 29/29] [lldb] [disassembler] chore: add variable annotator to
 scripting api: Docstrings update

Signed-off-by: Nikita B <[email protected]>
---
 lldb/bindings/interface/SBVariableAnnotatorDocstrings.i | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lldb/bindings/interface/SBVariableAnnotatorDocstrings.i 
b/lldb/bindings/interface/SBVariableAnnotatorDocstrings.i
index 2bc5a07e2cd83..de0aa4c051f73 100644
--- a/lldb/bindings/interface/SBVariableAnnotatorDocstrings.i
+++ b/lldb/bindings/interface/SBVariableAnnotatorDocstrings.i
@@ -12,7 +12,7 @@ The annotator extracts DWARF debug information to provide:
 * Address ranges where the location is valid
 * Source declaration information
 
-For example, when debugging optimized code:
+For example:
 
     annotator = lldb.SBVariableAnnotator()
     target = lldb.debugger.GetSelectedTarget()
@@ -63,7 +63,7 @@ lldb::SBVariableAnnotator::SBVariableAnnotator;
     * 'type_name' (string): Type name of the variable (optional)
 
     Args:
-        inst: SBInstruction object to annotate
+        inst: SBInstruction object
 
     Returns:
         SBStructuredData containing variable annotation array, or invalid

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

Reply via email to