https://github.com/n2h9 updated https://github.com/llvm/llvm-project/pull/169408

>From 7d0365815d838ba7ff926f6b9f5a8faf4590e052 Mon Sep 17 00:00:00 2001
From: Nikita B <[email protected]>
Date: Mon, 24 Nov 2025 21:02:52 +0100
Subject: [PATCH 1/8] [lldb] [disassembler] chore: enhance VariableAnnotator to
 return structured data: introduce VariableAnnotator::AnnotateStructured
 method

Signed-off-by: Nikita B <[email protected]>
---
 lldb/include/lldb/Core/Disassembler.h |  30 ++++++--
 lldb/source/Core/Disassembler.cpp     | 100 ++++++++++++++++++++------
 2 files changed, 102 insertions(+), 28 deletions(-)

diff --git a/lldb/include/lldb/Core/Disassembler.h 
b/lldb/include/lldb/Core/Disassembler.h
index 5de314109b0cc..a7922d4a4f703 100644
--- a/lldb/include/lldb/Core/Disassembler.h
+++ b/lldb/include/lldb/Core/Disassembler.h
@@ -570,24 +570,40 @@ class Disassembler : public 
std::enable_shared_from_this<Disassembler>,
   const Disassembler &operator=(const Disassembler &) = delete;
 };
 
+/// Structured data for a single variable annotation.
+struct VariableAnnotation {
+  std::string variable_name;
+  /// Location description (e.g., "r15", "undef", "const_0").
+  std::string location_description;
+  /// Whether variable is live at this instruction.
+  bool is_live;
+  /// Register numbering scheme for location interpretation.
+  lldb::RegisterKind register_kind;
+  /// Where this annotation is valid.
+  std::optional<lldb_private::AddressRange> address_range;
+  /// Source file where variable was declared.
+  std::optional<std::string> decl_file;
+  /// Line number where variable was declared.
+  std::optional<uint32_t> decl_line;
+  /// Variable's type name.
+  std::optional<std::string> type_name;
+};
+
 /// Tracks live variable annotations across instructions and produces
 /// per-instruction "events" like `name = RDI` or `name = <undef>`.
 class VariableAnnotator {
-  struct VarState {
-    /// Display name.
-    std::string name;
-    /// Last printed location (empty means <undef>).
-    std::string last_loc;
-  };
 
   // Live state from the previous instruction, keyed by Variable::GetID().
-  llvm::DenseMap<lldb::user_id_t, VarState> m_live_vars;
+  llvm::DenseMap<lldb::user_id_t, VariableAnnotation> m_live_vars;
 
 public:
   /// Compute annotation strings for a single instruction and update
   /// `m_live_vars`. Returns only the events that should be printed *at this
   /// instruction*.
   std::vector<std::string> Annotate(Instruction &inst);
+
+  /// Returns structured data for all variables relevant at this instruction.
+  std::vector<VariableAnnotation> AnnotateStructured(Instruction &inst);
 };
 
 } // namespace lldb_private
diff --git a/lldb/source/Core/Disassembler.cpp 
b/lldb/source/Core/Disassembler.cpp
index f2eb887986bfb..a2ebbe63cc9c6 100644
--- a/lldb/source/Core/Disassembler.cpp
+++ b/lldb/source/Core/Disassembler.cpp
@@ -286,6 +286,10 @@ bool Disassembler::ElideMixedSourceAndDisassemblyLine(
   return false;
 }
 
+static constexpr const char *UndefLocation = "undef";
+static const std::string UndefLocationFormatted =
+    llvm::formatv("<{0}>", UndefLocation).str();
+
 // For each instruction, this block attempts to resolve in-scope variables
 // and determine if the current PC falls within their
 // DWARF location entry. If so, it prints a simplified annotation using the
@@ -300,16 +304,41 @@ bool Disassembler::ElideMixedSourceAndDisassemblyLine(
 // disassembled instruction stream, similar to how debug information
 // enhances source-level debugging.
 std::vector<std::string> VariableAnnotator::Annotate(Instruction &inst) {
+  auto structured_annotations = AnnotateStructured(inst);
+
   std::vector<std::string> events;
+  events.reserve(structured_annotations.size());
+
+  for (const auto &annotation : structured_annotations) {
+    auto location = (annotation.location_description == UndefLocation
+                         ? UndefLocationFormatted
+                         : annotation.location_description);
+
+    auto display_string =
+        llvm::formatv("{0} = {1}", annotation.variable_name, location).str();
+
+    events.push_back(std::move(display_string));
+  }
+
+  return events;
+}
+
+std::vector<VariableAnnotation>
+VariableAnnotator::AnnotateStructured(Instruction &inst) {
+  std::vector<VariableAnnotation> annotations;
 
   auto module_sp = inst.GetAddress().GetModule();
 
-  // If we lost module context, everything becomes <undef>.
+  // If we lost module context, mark all live variables as UndefLocation.
   if (!module_sp) {
-    for (const auto &KV : m_live_vars)
-      events.emplace_back(llvm::formatv("{0} = <undef>", 
KV.second.name).str());
+    for (const auto &KV : m_live_vars) {
+      auto annotation_entity = KV.second;
+      annotation_entity.is_live = false;
+      annotation_entity.location_description = UndefLocation;
+      annotations.push_back(annotation_entity);
+    }
     m_live_vars.clear();
-    return events;
+    return annotations;
   }
 
   // Resolve function/block at this *file* address.
@@ -319,10 +348,14 @@ std::vector<std::string> 
VariableAnnotator::Annotate(Instruction &inst) {
   if (!module_sp->ResolveSymbolContextForAddress(iaddr, mask, sc) ||
       !sc.function) {
     // No function context: everything dies here.
-    for (const auto &KV : m_live_vars)
-      events.emplace_back(llvm::formatv("{0} = <undef>", 
KV.second.name).str());
+    for (const auto &KV : m_live_vars) {
+      auto annotation_entity = KV.second;
+      annotation_entity.is_live = false;
+      annotation_entity.location_description = UndefLocation;
+      annotations.push_back(annotation_entity);
+    }
     m_live_vars.clear();
-    return events;
+    return annotations;
   }
 
   // Collect in-scope variables for this instruction into current_vars.
@@ -349,7 +382,7 @@ std::vector<std::string> 
VariableAnnotator::Annotate(Instruction &inst) {
   // Prefer "register-only" output when we have an ABI.
   opts.PrintRegisterOnly = static_cast<bool>(abi_sp);
 
-  llvm::DenseMap<lldb::user_id_t, VarState> current_vars;
+  llvm::DenseMap<lldb::user_id_t, VariableAnnotation> current_vars;
 
   for (size_t i = 0, e = var_list.GetSize(); i != e; ++i) {
     lldb::VariableSP v = var_list.GetVariableAtIndex(i);
@@ -376,8 +409,26 @@ std::vector<std::string> 
VariableAnnotator::Annotate(Instruction &inst) {
     if (loc.empty())
       continue;
 
-    current_vars.try_emplace(v->GetID(),
-                             VarState{std::string(name), std::string(loc)});
+    std::optional<std::string> decl_file;
+    std::optional<uint32_t> decl_line;
+    std::optional<std::string> type_name;
+
+    const Declaration &decl = v->GetDeclaration();
+    if (decl.GetFile()) {
+      decl_file = decl.GetFile().GetFilename().AsCString();
+      if (decl.GetLine() > 0)
+        decl_line = decl.GetLine();
+    }
+
+    if (Type *type = v->GetType())
+      if (const char *type_str = type->GetName().AsCString())
+        type_name = type_str;
+
+    current_vars.try_emplace(
+        f v->GetID(),
+        VariableAnnotation{std::string(name), std::string(loc), true,
+                           entry.expr->GetRegisterKind(), entry.file_range,
+                           decl_file, decl_line, type_name});
   }
 
   // Diff m_live_vars → current_vars.
@@ -387,24 +438,31 @@ std::vector<std::string> 
VariableAnnotator::Annotate(Instruction &inst) {
     auto it = m_live_vars.find(KV.first);
     if (it == m_live_vars.end()) {
       // Newly live.
-      events.emplace_back(
-          llvm::formatv("{0} = {1}", KV.second.name, 
KV.second.last_loc).str());
-    } else if (it->second.last_loc != KV.second.last_loc) {
+      auto annotation_entity = KV.second;
+      annotation_entity.is_live = true;
+      annotations.push_back(annotation_entity);
+    } else if (it->second.location_description !=
+               KV.second.location_description) {
       // Location changed.
-      events.emplace_back(
-          llvm::formatv("{0} = {1}", KV.second.name, 
KV.second.last_loc).str());
+      auto annotation_entity = KV.second;
+      annotation_entity.is_live = true;
+      annotations.push_back(annotation_entity);
     }
   }
 
-  // 2) Ends: anything that was live but is not in current_vars becomes 
<undef>.
-  for (const auto &KV : m_live_vars) {
-    if (!current_vars.count(KV.first))
-      events.emplace_back(llvm::formatv("{0} = <undef>", 
KV.second.name).str());
-  }
+  // 2) Ends: anything that was live but is not in current_vars becomes
+  // UndefLocation.
+  for (const auto &KV : m_live_vars)
+    if (!current_vars.count(KV.first)) {
+      auto annotation_entity = KV.second;
+      annotation_entity.is_live = false;
+      annotation_entity.location_description = UndefLocation;
+      annotations.push_back(annotation_entity);
+    }
 
   // Commit new state.
   m_live_vars = std::move(current_vars);
-  return events;
+  return annotations;
 }
 
 void Disassembler::PrintInstructions(Debugger &debugger, const ArchSpec &arch,

>From 7e7ae0509108ac5c9337aaf18236b72a81d4dac9 Mon Sep 17 00:00:00 2001
From: Nikita B <[email protected]>
Date: Mon, 24 Nov 2025 21:24:03 +0100
Subject: [PATCH 2/8] [lldb] [disassembler] chore: enhance VariableAnnotator to
 return structured data: introduce VariableAnnotator::AnnotateStructured
 method: fix typo

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

diff --git a/lldb/source/Core/Disassembler.cpp 
b/lldb/source/Core/Disassembler.cpp
index a2ebbe63cc9c6..c695aa5d696b2 100644
--- a/lldb/source/Core/Disassembler.cpp
+++ b/lldb/source/Core/Disassembler.cpp
@@ -425,7 +425,7 @@ VariableAnnotator::AnnotateStructured(Instruction &inst) {
         type_name = type_str;
 
     current_vars.try_emplace(
-        f v->GetID(),
+        v->GetID(),
         VariableAnnotation{std::string(name), std::string(loc), true,
                            entry.expr->GetRegisterKind(), entry.file_range,
                            decl_file, decl_line, type_name});

>From 4b601f8d52aaa82d94096280e15d3d3bfe037610 Mon Sep 17 00:00:00 2001
From: n2h9 <[email protected]>
Date: Wed, 26 Nov 2025 21:51:27 +0100
Subject: [PATCH 3/8] Update lldb/source/Core/Disassembler.cpp

Co-authored-by: Jonas Devlieghere <[email protected]>
---
 lldb/source/Core/Disassembler.cpp | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/lldb/source/Core/Disassembler.cpp 
b/lldb/source/Core/Disassembler.cpp
index c695aa5d696b2..0edeeb9d2eac4 100644
--- a/lldb/source/Core/Disassembler.cpp
+++ b/lldb/source/Core/Disassembler.cpp
@@ -286,9 +286,8 @@ bool Disassembler::ElideMixedSourceAndDisassemblyLine(
   return false;
 }
 
-static constexpr const char *UndefLocation = "undef";
-static const std::string UndefLocationFormatted =
-    llvm::formatv("<{0}>", UndefLocation).str();
+static constexpr const llvm::StringLiteral kUndefLocation = "undef";
+static contexpr const llvm::StringLiteral kUndefLocationFormatted = "<undef>";
 
 // For each instruction, this block attempts to resolve in-scope variables
 // and determine if the current PC falls within their

>From 3654a864c24d45d74ac4d393b541a265e6f3a955 Mon Sep 17 00:00:00 2001
From: Nikita B <[email protected]>
Date: Wed, 26 Nov 2025 22:34:20 +0100
Subject: [PATCH 4/8] [lldb] [disassembler] chore: enhance VariableAnnotator to
 return structured data: introduce VariableAnnotator::AnnotateStructured
 method: replace auto with actual type where type is not obvious; add const
 modifier to local variables which are read only

Signed-off-by: Nikita B <[email protected]>
---
 lldb/source/Core/Disassembler.cpp | 28 +++++++++++++++-------------
 1 file changed, 15 insertions(+), 13 deletions(-)

diff --git a/lldb/source/Core/Disassembler.cpp 
b/lldb/source/Core/Disassembler.cpp
index 0edeeb9d2eac4..985a0ce56e8c2 100644
--- a/lldb/source/Core/Disassembler.cpp
+++ b/lldb/source/Core/Disassembler.cpp
@@ -287,7 +287,7 @@ bool Disassembler::ElideMixedSourceAndDisassemblyLine(
 }
 
 static constexpr const llvm::StringLiteral kUndefLocation = "undef";
-static contexpr const llvm::StringLiteral kUndefLocationFormatted = "<undef>";
+static constexpr const llvm::StringLiteral kUndefLocationFormatted = "<undef>";
 
 // For each instruction, this block attempts to resolve in-scope variables
 // and determine if the current PC falls within their
@@ -303,17 +303,19 @@ static contexpr const llvm::StringLiteral 
kUndefLocationFormatted = "<undef>";
 // disassembled instruction stream, similar to how debug information
 // enhances source-level debugging.
 std::vector<std::string> VariableAnnotator::Annotate(Instruction &inst) {
-  auto structured_annotations = AnnotateStructured(inst);
+  std::vector<VariableAnnotation> structured_annotations =
+      AnnotateStructured(inst);
 
   std::vector<std::string> events;
   events.reserve(structured_annotations.size());
 
   for (const auto &annotation : structured_annotations) {
-    auto location = (annotation.location_description == UndefLocation
-                         ? UndefLocationFormatted
-                         : annotation.location_description);
+    const llvm::StringRef location =
+        (annotation.location_description == kUndefLocation
+             ? llvm::StringRef(kUndefLocationFormatted)
+             : llvm::StringRef(annotation.location_description));
 
-    auto display_string =
+    const auto display_string =
         llvm::formatv("{0} = {1}", annotation.variable_name, location).str();
 
     events.push_back(std::move(display_string));
@@ -331,9 +333,9 @@ VariableAnnotator::AnnotateStructured(Instruction &inst) {
   // If we lost module context, mark all live variables as UndefLocation.
   if (!module_sp) {
     for (const auto &KV : m_live_vars) {
-      auto annotation_entity = KV.second;
+      VariableAnnotation annotation_entity = KV.second;
       annotation_entity.is_live = false;
-      annotation_entity.location_description = UndefLocation;
+      annotation_entity.location_description = kUndefLocation;
       annotations.push_back(annotation_entity);
     }
     m_live_vars.clear();
@@ -348,9 +350,9 @@ VariableAnnotator::AnnotateStructured(Instruction &inst) {
       !sc.function) {
     // No function context: everything dies here.
     for (const auto &KV : m_live_vars) {
-      auto annotation_entity = KV.second;
+      VariableAnnotation annotation_entity = KV.second;
       annotation_entity.is_live = false;
-      annotation_entity.location_description = UndefLocation;
+      annotation_entity.location_description = kUndefLocation;
       annotations.push_back(annotation_entity);
     }
     m_live_vars.clear();
@@ -437,13 +439,13 @@ VariableAnnotator::AnnotateStructured(Instruction &inst) {
     auto it = m_live_vars.find(KV.first);
     if (it == m_live_vars.end()) {
       // Newly live.
-      auto annotation_entity = KV.second;
+      VariableAnnotation annotation_entity = KV.second;
       annotation_entity.is_live = true;
       annotations.push_back(annotation_entity);
     } else if (it->second.location_description !=
                KV.second.location_description) {
       // Location changed.
-      auto annotation_entity = KV.second;
+      VariableAnnotation annotation_entity = KV.second;
       annotation_entity.is_live = true;
       annotations.push_back(annotation_entity);
     }
@@ -455,7 +457,7 @@ VariableAnnotator::AnnotateStructured(Instruction &inst) {
     if (!current_vars.count(KV.first)) {
       auto annotation_entity = KV.second;
       annotation_entity.is_live = false;
-      annotation_entity.location_description = UndefLocation;
+      annotation_entity.location_description = kUndefLocation;
       annotations.push_back(annotation_entity);
     }
 

>From 110c041b63a4a06bfe6e7ed20b177455798a66f3 Mon Sep 17 00:00:00 2001
From: Nikita B <[email protected]>
Date: Wed, 26 Nov 2025 22:36:02 +0100
Subject: [PATCH 5/8] [lldb] [disassembler] chore: enhance VariableAnnotator to
 return structured data: introduce VariableAnnotator::AnnotateStructured
 method: add std::move when push back annotation entity into vector

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

diff --git a/lldb/source/Core/Disassembler.cpp 
b/lldb/source/Core/Disassembler.cpp
index 985a0ce56e8c2..117c13a1233cd 100644
--- a/lldb/source/Core/Disassembler.cpp
+++ b/lldb/source/Core/Disassembler.cpp
@@ -336,7 +336,7 @@ VariableAnnotator::AnnotateStructured(Instruction &inst) {
       VariableAnnotation annotation_entity = KV.second;
       annotation_entity.is_live = false;
       annotation_entity.location_description = kUndefLocation;
-      annotations.push_back(annotation_entity);
+      annotations.push_back(std::move(annotation_entity));
     }
     m_live_vars.clear();
     return annotations;
@@ -353,7 +353,7 @@ VariableAnnotator::AnnotateStructured(Instruction &inst) {
       VariableAnnotation annotation_entity = KV.second;
       annotation_entity.is_live = false;
       annotation_entity.location_description = kUndefLocation;
-      annotations.push_back(annotation_entity);
+      annotations.push_back(std::move(annotation_entity));
     }
     m_live_vars.clear();
     return annotations;
@@ -441,13 +441,13 @@ VariableAnnotator::AnnotateStructured(Instruction &inst) {
       // Newly live.
       VariableAnnotation annotation_entity = KV.second;
       annotation_entity.is_live = true;
-      annotations.push_back(annotation_entity);
+      annotations.push_back(std::move(annotation_entity));
     } else if (it->second.location_description !=
                KV.second.location_description) {
       // Location changed.
       VariableAnnotation annotation_entity = KV.second;
       annotation_entity.is_live = true;
-      annotations.push_back(annotation_entity);
+      annotations.push_back(std::move(annotation_entity));
     }
   }
 
@@ -458,7 +458,7 @@ VariableAnnotator::AnnotateStructured(Instruction &inst) {
       auto annotation_entity = KV.second;
       annotation_entity.is_live = false;
       annotation_entity.location_description = kUndefLocation;
-      annotations.push_back(annotation_entity);
+      annotations.push_back(std::move(annotation_entity));
     }
 
   // Commit new state.

>From d1802aa920eebf6b7574a7cc15d6094472e0e682 Mon Sep 17 00:00:00 2001
From: n2h9 <[email protected]>
Date: Wed, 3 Dec 2025 01:17:02 +0100
Subject: [PATCH 6/8] Update lldb/source/Core/Disassembler.cpp

Co-authored-by: Jonas Devlieghere <[email protected]>
---
 lldb/source/Core/Disassembler.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lldb/source/Core/Disassembler.cpp 
b/lldb/source/Core/Disassembler.cpp
index 117c13a1233cd..42cf701cf4276 100644
--- a/lldb/source/Core/Disassembler.cpp
+++ b/lldb/source/Core/Disassembler.cpp
@@ -309,7 +309,7 @@ std::vector<std::string> 
VariableAnnotator::Annotate(Instruction &inst) {
   std::vector<std::string> events;
   events.reserve(structured_annotations.size());
 
-  for (const auto &annotation : structured_annotations) {
+  for (const VariableAnnotation &annotation : structured_annotations) {
     const llvm::StringRef location =
         (annotation.location_description == kUndefLocation
              ? llvm::StringRef(kUndefLocationFormatted)

>From 43e1b8f3a96004f7c7229d513efeb84a3712b486 Mon Sep 17 00:00:00 2001
From: n2h9 <[email protected]>
Date: Wed, 3 Dec 2025 01:17:35 +0100
Subject: [PATCH 7/8] Update lldb/source/Core/Disassembler.cpp

Co-authored-by: Jonas Devlieghere <[email protected]>
---
 lldb/source/Core/Disassembler.cpp | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/lldb/source/Core/Disassembler.cpp 
b/lldb/source/Core/Disassembler.cpp
index 42cf701cf4276..b2fb10d5afdda 100644
--- a/lldb/source/Core/Disassembler.cpp
+++ b/lldb/source/Core/Disassembler.cpp
@@ -315,10 +315,7 @@ std::vector<std::string> 
VariableAnnotator::Annotate(Instruction &inst) {
              ? llvm::StringRef(kUndefLocationFormatted)
              : llvm::StringRef(annotation.location_description));
 
-    const auto display_string =
-        llvm::formatv("{0} = {1}", annotation.variable_name, location).str();
-
-    events.push_back(std::move(display_string));
+    events.push_back(llvm::formatv("{0} = {1}", annotation.variable_name, 
location).str());
   }
 
   return events;

>From b4058bfb7a4f0848c8b3f1a609549a4416c9681b Mon Sep 17 00:00:00 2001
From: Nikita B <[email protected]>
Date: Wed, 3 Dec 2025 01:25:12 +0100
Subject: [PATCH 8/8] [lldb] [disassembler] chore: enhance VariableAnnotator to
 return structured data: introduce VariableAnnotator::AnnotateStructured
 method: formatting

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

diff --git a/lldb/source/Core/Disassembler.cpp 
b/lldb/source/Core/Disassembler.cpp
index b2fb10d5afdda..9b7ac5fc9a9cc 100644
--- a/lldb/source/Core/Disassembler.cpp
+++ b/lldb/source/Core/Disassembler.cpp
@@ -315,7 +315,8 @@ std::vector<std::string> 
VariableAnnotator::Annotate(Instruction &inst) {
              ? llvm::StringRef(kUndefLocationFormatted)
              : llvm::StringRef(annotation.location_description));
 
-    events.push_back(llvm::formatv("{0} = {1}", annotation.variable_name, 
location).str());
+    events.push_back(
+        llvm::formatv("{0} = {1}", annotation.variable_name, location).str());
   }
 
   return events;

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

Reply via email to