[Lldb-commits] [lldb] [lldb] [disassembler] chore: enhance VariableAnnotator to return structured data: implement SBVariableAnnotator class for Scripting Bridge API (PR #174847)
via lldb-commits
lldb-commits at lists.llvm.org
Thu Jan 15 12:57:08 PST 2026
https://github.com/n2h9 updated https://github.com/llvm/llvm-project/pull/174847
>From ee97426b0e0e509be8315e38fe48d752f9db0cb4 Mon Sep 17 00:00:00 2001
From: Nikita B <n2h9z4 at gmail.com>
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 <n2h9z4 at gmail.com>
---
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 <n2h9z4 at gmail.com>
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 <n2h9z4 at gmail.com>
---
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 <n2h9z4 at gmail.com>
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 <n2h9z4 at gmail.com>
---
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 <n2h9z4 at gmail.com>
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 <n2h9z4 at gmail.com>
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 <n2h9z4 at gmail.com>
---
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 <n2h9z4 at gmail.com>
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 <n2h9z4 at gmail.com>
---
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 <n2h9z4 at gmail.com>
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 <n2h9z4 at gmail.com>
---
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 <n2h9z4 at gmail.com>
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 <n2h9z4 at gmail.com>
---
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 <n2h9z4 at gmail.com>
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 <n2h9z4 at gmail.com>
---
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 <n2h9z4 at gmail.com>
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 <n2h9z4 at gmail.com>
---
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 <n2h9z4 at gmail.com>
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 <n2h9z4 at gmail.com>
---
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 <n2h9z4 at gmail.com>
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 <n2h9z4 at gmail.com>
---
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 <n2h9z4 at gmail.com>
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 <n2h9z4 at gmail.com>
---
.../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 <n2h9z4 at gmail.com>
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 <n2h9z4 at gmail.com>
---
.../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 <n2h9z4 at gmail.com>
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 <n2h9z4 at gmail.com>
---
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 <n2h9z4 at gmail.com>
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 <n2h9z4 at gmail.com>
---
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 <n2h9z4 at gmail.com>
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 <n2h9z4 at gmail.com>
---
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 <n2h9z4 at gmail.com>
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 <n2h9z4 at gmail.com>
---
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 <n2h9z4 at gmail.com>
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 <n2h9z4 at gmail.com>
---
.../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 <n2h9z4 at gmail.com>
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 <n2h9z4 at gmail.com>
---
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 <n2h9z4 at gmail.com>
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 <n2h9z4 at gmail.com>
---
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 <n2h9z4 at gmail.com>
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 <n2h9z4 at gmail.com>
---
.../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 <n2h9z4 at gmail.com>
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 <n2h9z4 at gmail.com>
---
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 <n2h9z4 at gmail.com>
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 <n2h9z4 at gmail.com>
---
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 <n2h9z4 at gmail.com>
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 <n2h9z4 at gmail.com>
---
.../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 <n2h9z4 at gmail.com>
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 <n2h9z4 at gmail.com>
---
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 <n2h9z4 at gmail.com>
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 <n2h9z4 at gmail.com>
---
.../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 <n2h9z4 at gmail.com>
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 <n2h9z4 at gmail.com>
---
.../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 <n2h9z4 at gmail.com>
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 <n2h9z4 at gmail.com>
---
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
More information about the lldb-commits
mailing list