Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Tom Tromey <tromey@adacore.com>
To: gdb-patches@sourceware.org
Cc: Tom Tromey <tromey@adacore.com>
Subject: [PATCH] Add evaluateName to registers returned by DAP
Date: Thu,  3 Sep 2026 12:40:41 -0600	[thread overview]
Message-ID: <20260903184042.3954699-1-tromey@adacore.com> (raw)

This patch adds the evaluateName field to register variables returned
by DAP.

This isn't truly complete, in that referring to a sub-part of a
register won't have an evaluateName.  This is a larger problem,
though, and requires a solution for pretty-printers as well.

Meanwhile, this patch helps with a pretty typical case.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33407
---
 gdb/python/lib/gdb/dap/bt.py         |  2 +-
 gdb/python/lib/gdb/dap/globalvars.py |  2 +-
 gdb/python/lib/gdb/dap/scopes.py     | 18 +++++++++++-------
 gdb/python/lib/gdb/dap/varref.py     | 17 +++++++++++------
 gdb/testsuite/gdb.dap/scopes.exp     |  6 ++++++
 5 files changed, 30 insertions(+), 15 deletions(-)

diff --git a/gdb/python/lib/gdb/dap/bt.py b/gdb/python/lib/gdb/dap/bt.py
index b8976e54698..38eaea7759d 100644
--- a/gdb/python/lib/gdb/dap/bt.py
+++ b/gdb/python/lib/gdb/dap/bt.py
@@ -38,7 +38,7 @@ def _compute_parameters(frame, stack_format):
     result = []
     for arg in arg_iter:
         desc = []
-        name, val = symbol_value(arg, frame)
+        name, val, _ = symbol_value(arg, frame)
         # We don't try to use any particular language's syntax for the
         # output here.
         if stack_format["parameterTypes"]:
diff --git a/gdb/python/lib/gdb/dap/globalvars.py b/gdb/python/lib/gdb/dap/globalvars.py
index c90404362c4..70b1f64e24f 100644
--- a/gdb/python/lib/gdb/dap/globalvars.py
+++ b/gdb/python/lib/gdb/dap/globalvars.py
@@ -61,7 +61,7 @@ class _Globals(BaseReference):
     @in_gdb_thread
     def fetch_one_child(self, idx):
         sym = self._var_list[idx]
-        return (sym.print_name, sym.value())
+        return (sym.print_name, sym.value(), None)
 
 
 @in_gdb_thread
diff --git a/gdb/python/lib/gdb/dap/scopes.py b/gdb/python/lib/gdb/dap/scopes.py
index 98a710f2df5..2b88a2fd15b 100644
--- a/gdb/python/lib/gdb/dap/scopes.py
+++ b/gdb/python/lib/gdb/dap/scopes.py
@@ -55,8 +55,9 @@ def set_finish_value(val):
 # A helper function to compute the value of a symbol.  SYM is either a
 # gdb.Symbol, or an object implementing the SymValueWrapper interface.
 # FRAME is a frame wrapper, as produced by a frame filter.  Returns a
-# tuple of the form (NAME, VALUE), where NAME is the symbol's name and
-# VALUE is a gdb.Value.
+# tuple of the form (NAME, VALUE, None), where NAME is the symbol's
+# name and VALUE is a gdb.Value.  The 'None' is returned because this
+# function is called by fetch_one_child.
 @in_gdb_thread
 def symbol_value(sym, frame):
     inf_frame = frame.inferior_frame()
@@ -72,7 +73,7 @@ def symbol_value(sym, frame):
         val = sym.symbol().value(inf_frame)
     elif not isinstance(val, gdb.Value):
         val = gdb.Value(val)
-    return (name, val)
+    return (name, val, None)
 
 
 class _ScopeReference(BaseReference):
@@ -120,7 +121,9 @@ class _FinishScopeReference(_ScopeReference):
 
     def fetch_one_child(self, idx):
         assert idx == 0
-        return ("(return)", _last_return_value)
+        # It might be nice to return an evaluateName here; maybe this
+        # could be done by introducing a convenience variable.
+        return ("(return)", _last_return_value, None)
 
 
 class _RegisterReference(_ScopeReference):
@@ -134,12 +137,13 @@ class _RegisterReference(_ScopeReference):
 
     @in_gdb_thread
     def fetch_one_child(self, idx):
-        return (
-            self._var_list[idx].name,
+        name = self._var_list[idx].name
+        value = (
             frame_for_id(self._frameId)
             .inferior_frame()
-            .read_register(self._var_list[idx]),
+            .read_register(self._var_list[idx])
         )
+        return (name, value, "$" + name)
 
 
 @request("scopes")
diff --git a/gdb/python/lib/gdb/dap/varref.py b/gdb/python/lib/gdb/dap/varref.py
index e2dcd03910c..cd0321a7c82 100644
--- a/gdb/python/lib/gdb/dap/varref.py
+++ b/gdb/python/lib/gdb/dap/varref.py
@@ -107,8 +107,10 @@ class BaseReference(ABC):
         """Fetch one child of this variable.
 
         INDEX is the index of the child to fetch.
-        This should return a tuple of the form (NAME, VALUE), where
-        NAME is the name of the variable, and VALUE is a gdb.Value."""
+        This should return a tuple of the form (NAME, VALUE, EVAL_NAME),
+        where NAME is the name of the variable, and VALUE is a gdb.Value.
+        EVAL_NAME may either be None, or a string that is used as the
+        variable's 'evaluateName'."""
         return
 
     @abstractmethod
@@ -153,9 +155,9 @@ class BaseReference(ABC):
             if idx >= len(self._children):
                 break
             if self._children[idx] is None:
-                name, value = self.fetch_one_child(idx)
+                name, value, eval_name = self.fetch_one_child(idx)
                 name = self._compute_name(name)
-                var = VariableReference(name, value)
+                var = VariableReference(name, value, eval_name=eval_name)
                 self._children[idx] = var
                 self._by_name[name] = var
             yield self._children[idx]
@@ -176,7 +178,7 @@ class BaseReference(ABC):
 class VariableReference(BaseReference):
     """Concrete subclass of BaseReference that handles gdb.Value."""
 
-    def __init__(self, name, value, result_name="value"):
+    def __init__(self, name, value, result_name="value", eval_name=None):
         """Initializer.
 
         NAME is the name of this reference, see superclass.
@@ -186,6 +188,7 @@ class VariableReference(BaseReference):
         super().__init__(name)
         self._result_name = result_name
         self._value = value
+        self._eval_name = eval_name
         self._update_value()
 
     # Internal method to update local data when the value changes.
@@ -261,6 +264,8 @@ class VariableReference(BaseReference):
                 result["memoryReference"] = hex(int(self._value))
         if client_bool_capability("supportsVariableType"):
             result["type"] = str(self._value.type)
+        if self._eval_name is not None:
+            result["evaluateName"] = self._eval_name
         return result
 
     @in_gdb_thread
@@ -275,7 +280,7 @@ class VariableReference(BaseReference):
         # gdb.Value, but it must be convertible.
         if not isinstance(val, gdb.Value):
             val = gdb.Value(val)
-        return (name, val)
+        return (name, val, None)
 
 
 @in_gdb_thread
diff --git a/gdb/testsuite/gdb.dap/scopes.exp b/gdb/testsuite/gdb.dap/scopes.exp
index d22d39cbf8b..eb3e6a5e04f 100644
--- a/gdb/testsuite/gdb.dap/scopes.exp
+++ b/gdb/testsuite/gdb.dap/scopes.exp
@@ -153,6 +153,12 @@ lassign [dap_check_request_and_response "fetch all registers" \
 # If any register has children, try to fetch those as well.  This is a
 # regression test for part of PR dap/33228.
 foreach var [dict get $val body variables] {
+    # Check that gdb emits an evaluateName for each register.
+    set name [dict get $var name]
+    set evalName [dict get $var evaluateName]
+    gdb_assert {[string cat "$" $name] == $evalName} \
+	"evaluateName for register $name"
+
     set regvar [dict get $var variablesReference]
     if {$regvar > 0} {
 	# If variablesReference is non-zero, then there must be either

base-commit: 2986ed8ba365f7e583e2f6c9098ea5ec57ee50e1
-- 
2.55.0


                 reply	other threads:[~2026-09-03 18:41 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260903184042.3954699-1-tromey@adacore.com \
    --to=tromey@adacore.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox