[Lldb-commits] [lldb] [lldb] Update dwim-print to support limited variable expression paths (PR #117452)

2024-11-23 Thread Dave Lee via lldb-commits

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

>From cce676f2e8e0ed7a81ae1fa78082765cb698de85 Mon Sep 17 00:00:00 2001
From: Dave Lee 
Date: Sat, 23 Nov 2024 14:37:10 -0800
Subject: [PATCH 1/2] [lldb] Update dwim-print to support limited variable
 expression paths

`frame variable` supports nested variable access, which the API calls "variable
expression paths". This change updates `dwim-print` to support a subset of 
supported
variable expression paths.

Consider the expression `a->b`. In C++, the arrow operator can be overloaded, 
and where
that is the case, expression evaluation must be used to evaluate it, not frame 
variable.
Likewise, the subscript operator can be overloaded.

To avoid those cases, this change introduces a limited support for variable 
expression
paths. Use of the dot operator is allowed.

Additionally, this change allows `dwim-print` to directly access children of 
`this` and
`self` (see AllowDirectIVarAccess). This functionality is also provided by the 
same
`GetValueForVariableExpressionPath` method.

rdar://104348908
---
 .../Commands/CommandObjectDWIMPrint.cpp   | 21 +++--
 lldb/test/API/commands/dwim-print/Makefile|  2 +-
 .../API/commands/dwim-print/TestDWIMPrint.py  | 43 ---
 lldb/test/API/commands/dwim-print/main.c  | 14 --
 lldb/test/API/commands/dwim-print/main.cpp| 22 ++
 5 files changed, 76 insertions(+), 26 deletions(-)
 delete mode 100644 lldb/test/API/commands/dwim-print/main.c
 create mode 100644 lldb/test/API/commands/dwim-print/main.cpp

diff --git a/lldb/source/Commands/CommandObjectDWIMPrint.cpp 
b/lldb/source/Commands/CommandObjectDWIMPrint.cpp
index 62c4e74d853ad1..842ff6e1466d63 100644
--- a/lldb/source/Commands/CommandObjectDWIMPrint.cpp
+++ b/lldb/source/Commands/CommandObjectDWIMPrint.cpp
@@ -151,10 +151,23 @@ void CommandObjectDWIMPrint::DoExecute(StringRef command,
 result.SetStatus(eReturnStatusSuccessFinishResult);
   };
 
-  // First, try `expr` as the name of a frame variable.
-  if (frame) {
-auto valobj_sp = frame->FindVariable(ConstString(expr));
-if (valobj_sp && valobj_sp->GetError().Success()) {
+  // First, try `expr` as a _limited_ frame variable expression path: only the
+  // dot operator (`.`) is permitted for this case.
+  //
+  // This is limited to support only unambiguous expression paths. Of note,
+  // expression paths are not attempted if the expression contain either the
+  // arrow operator (`->`) or the subscript operator (`[]`). This is because
+  // both operators can be overloaded in C++, and could result in ambiguity in
+  // how the expression is handled. Additionally, `*` and `&` are not 
supported.
+  bool try_variable_path = expr.find_first_of("*&->[]") == StringRef::npos;
+  if (frame && try_variable_path) {
+Status status;
+VariableSP var_sp;
+auto valobj_sp = frame->GetValueForVariableExpressionPath(
+expr, eDynamicDontRunTarget,
+StackFrame::eExpressionPathOptionsAllowDirectIVarAccess, var_sp,
+status);
+if (valobj_sp && status.Success() && valobj_sp->GetError().Success()) {
   if (!suppress_result) {
 if (auto persisted_valobj = valobj_sp->Persist())
   valobj_sp = persisted_valobj;
diff --git a/lldb/test/API/commands/dwim-print/Makefile 
b/lldb/test/API/commands/dwim-print/Makefile
index 10495940055b63..8b20bcb050 100644
--- a/lldb/test/API/commands/dwim-print/Makefile
+++ b/lldb/test/API/commands/dwim-print/Makefile
@@ -1,3 +1,3 @@
-C_SOURCES := main.c
+CXX_SOURCES := main.cpp
 
 include Makefile.rules
diff --git a/lldb/test/API/commands/dwim-print/TestDWIMPrint.py 
b/lldb/test/API/commands/dwim-print/TestDWIMPrint.py
index b40924a182e37d..492d49f008a9e4 100644
--- a/lldb/test/API/commands/dwim-print/TestDWIMPrint.py
+++ b/lldb/test/API/commands/dwim-print/TestDWIMPrint.py
@@ -16,7 +16,7 @@ def _run_cmd(self, cmd: str) -> str:
 self.ci.HandleCommand(cmd, result)
 return result.GetOutput().rstrip()
 
-VAR_IDENT = re.compile(r"(?:\$\d+|\w+) = ")
+VAR_IDENT = re.compile(r"(?:\$\d+|[\w.]+) = ")
 
 def _strip_result_var(self, string: str) -> str:
 """
@@ -121,30 +121,39 @@ def test_empty_expression(self):
 def test_nested_values(self):
 """Test dwim-print with nested values (structs, etc)."""
 self.build()
-lldbutil.run_to_source_breakpoint(self, "break here", 
lldb.SBFileSpec("main.c"))
+lldbutil.run_to_source_breakpoint(
+self, "break here", lldb.SBFileSpec("main.cpp")
+)
 self.runCmd("settings set auto-one-line-summaries false")
 self._expect_cmd(f"dwim-print s", "frame variable")
 self._expect_cmd(f"dwim-print (struct Structure)s", "expression")
 
 def test_summary_strings(self):
-"""Test dwim-print with nested values (structs, etc)."""
+"""Test dwim-print with type summaries."""
 self.build()
-lldbutil

[Lldb-commits] [lldb] [lldb] Update dwim-print to support limited variable expression paths (PR #117452)

2024-11-23 Thread Dave Lee via lldb-commits

https://github.com/kastiglione created 
https://github.com/llvm/llvm-project/pull/117452

`frame variable` supports nested variable access, which the API calls "variable
expression paths". This change updates `dwim-print` to support a subset of 
supported
variable expression paths.

Consider the expression `a->b`. In C++, the arrow operator can be overloaded, 
and where
that is the case, expression evaluation must be used to evaluate it, not frame 
variable.
Likewise, the subscript operator can be overloaded.

To avoid those cases, this change introduces a limited support for variable 
expression
paths. Use of the dot operator is allowed.

Additionally, this change allows `dwim-print` to directly access children of 
`this` and
`self` (see AllowDirectIVarAccess). This functionality is also provided by the 
same
`GetValueForVariableExpressionPath` method.

rdar://104348908


>From cce676f2e8e0ed7a81ae1fa78082765cb698de85 Mon Sep 17 00:00:00 2001
From: Dave Lee 
Date: Sat, 23 Nov 2024 14:37:10 -0800
Subject: [PATCH] [lldb] Update dwim-print to support limited variable
 expression paths

`frame variable` supports nested variable access, which the API calls "variable
expression paths". This change updates `dwim-print` to support a subset of 
supported
variable expression paths.

Consider the expression `a->b`. In C++, the arrow operator can be overloaded, 
and where
that is the case, expression evaluation must be used to evaluate it, not frame 
variable.
Likewise, the subscript operator can be overloaded.

To avoid those cases, this change introduces a limited support for variable 
expression
paths. Use of the dot operator is allowed.

Additionally, this change allows `dwim-print` to directly access children of 
`this` and
`self` (see AllowDirectIVarAccess). This functionality is also provided by the 
same
`GetValueForVariableExpressionPath` method.

rdar://104348908
---
 .../Commands/CommandObjectDWIMPrint.cpp   | 21 +++--
 lldb/test/API/commands/dwim-print/Makefile|  2 +-
 .../API/commands/dwim-print/TestDWIMPrint.py  | 43 ---
 lldb/test/API/commands/dwim-print/main.c  | 14 --
 lldb/test/API/commands/dwim-print/main.cpp| 22 ++
 5 files changed, 76 insertions(+), 26 deletions(-)
 delete mode 100644 lldb/test/API/commands/dwim-print/main.c
 create mode 100644 lldb/test/API/commands/dwim-print/main.cpp

diff --git a/lldb/source/Commands/CommandObjectDWIMPrint.cpp 
b/lldb/source/Commands/CommandObjectDWIMPrint.cpp
index 62c4e74d853ad1..842ff6e1466d63 100644
--- a/lldb/source/Commands/CommandObjectDWIMPrint.cpp
+++ b/lldb/source/Commands/CommandObjectDWIMPrint.cpp
@@ -151,10 +151,23 @@ void CommandObjectDWIMPrint::DoExecute(StringRef command,
 result.SetStatus(eReturnStatusSuccessFinishResult);
   };
 
-  // First, try `expr` as the name of a frame variable.
-  if (frame) {
-auto valobj_sp = frame->FindVariable(ConstString(expr));
-if (valobj_sp && valobj_sp->GetError().Success()) {
+  // First, try `expr` as a _limited_ frame variable expression path: only the
+  // dot operator (`.`) is permitted for this case.
+  //
+  // This is limited to support only unambiguous expression paths. Of note,
+  // expression paths are not attempted if the expression contain either the
+  // arrow operator (`->`) or the subscript operator (`[]`). This is because
+  // both operators can be overloaded in C++, and could result in ambiguity in
+  // how the expression is handled. Additionally, `*` and `&` are not 
supported.
+  bool try_variable_path = expr.find_first_of("*&->[]") == StringRef::npos;
+  if (frame && try_variable_path) {
+Status status;
+VariableSP var_sp;
+auto valobj_sp = frame->GetValueForVariableExpressionPath(
+expr, eDynamicDontRunTarget,
+StackFrame::eExpressionPathOptionsAllowDirectIVarAccess, var_sp,
+status);
+if (valobj_sp && status.Success() && valobj_sp->GetError().Success()) {
   if (!suppress_result) {
 if (auto persisted_valobj = valobj_sp->Persist())
   valobj_sp = persisted_valobj;
diff --git a/lldb/test/API/commands/dwim-print/Makefile 
b/lldb/test/API/commands/dwim-print/Makefile
index 10495940055b63..8b20bcb050 100644
--- a/lldb/test/API/commands/dwim-print/Makefile
+++ b/lldb/test/API/commands/dwim-print/Makefile
@@ -1,3 +1,3 @@
-C_SOURCES := main.c
+CXX_SOURCES := main.cpp
 
 include Makefile.rules
diff --git a/lldb/test/API/commands/dwim-print/TestDWIMPrint.py 
b/lldb/test/API/commands/dwim-print/TestDWIMPrint.py
index b40924a182e37d..492d49f008a9e4 100644
--- a/lldb/test/API/commands/dwim-print/TestDWIMPrint.py
+++ b/lldb/test/API/commands/dwim-print/TestDWIMPrint.py
@@ -16,7 +16,7 @@ def _run_cmd(self, cmd: str) -> str:
 self.ci.HandleCommand(cmd, result)
 return result.GetOutput().rstrip()
 
-VAR_IDENT = re.compile(r"(?:\$\d+|\w+) = ")
+VAR_IDENT = re.compile(r"(?:\$\d+|[\w.]+) = ")
 
 def _strip_result_var(self, string: str) -> str:
 

[Lldb-commits] [lldb] [lldb] Update dwim-print to support limited variable expression paths (PR #117452)

2024-11-23 Thread via lldb-commits

llvmbot wrote:




@llvm/pr-subscribers-lldb

Author: Dave Lee (kastiglione)


Changes

`frame variable` supports nested variable access, which the API calls "variable
expression paths". This change updates `dwim-print` to support a subset of 
supported
variable expression paths.

Consider the expression `a->b`. In C++, the arrow operator can be 
overloaded, and where
that is the case, expression evaluation must be used to evaluate it, not frame 
variable.
Likewise, the subscript operator can be overloaded.

To avoid those cases, this change introduces a limited support for variable 
expression
paths. Use of the dot operator is allowed.

Additionally, this change allows `dwim-print` to directly access children of 
`this` and
`self` (see AllowDirectIVarAccess). This functionality is also provided by the 
same
`GetValueForVariableExpressionPath` method.

rdar://104348908


---
Full diff: https://github.com/llvm/llvm-project/pull/117452.diff


5 Files Affected:

- (modified) lldb/source/Commands/CommandObjectDWIMPrint.cpp (+17-4) 
- (modified) lldb/test/API/commands/dwim-print/Makefile (+1-1) 
- (modified) lldb/test/API/commands/dwim-print/TestDWIMPrint.py (+36-7) 
- (removed) lldb/test/API/commands/dwim-print/main.c (-14) 
- (added) lldb/test/API/commands/dwim-print/main.cpp (+22) 


``diff
diff --git a/lldb/source/Commands/CommandObjectDWIMPrint.cpp 
b/lldb/source/Commands/CommandObjectDWIMPrint.cpp
index 62c4e74d853ad1..842ff6e1466d63 100644
--- a/lldb/source/Commands/CommandObjectDWIMPrint.cpp
+++ b/lldb/source/Commands/CommandObjectDWIMPrint.cpp
@@ -151,10 +151,23 @@ void CommandObjectDWIMPrint::DoExecute(StringRef command,
 result.SetStatus(eReturnStatusSuccessFinishResult);
   };
 
-  // First, try `expr` as the name of a frame variable.
-  if (frame) {
-auto valobj_sp = frame->FindVariable(ConstString(expr));
-if (valobj_sp && valobj_sp->GetError().Success()) {
+  // First, try `expr` as a _limited_ frame variable expression path: only the
+  // dot operator (`.`) is permitted for this case.
+  //
+  // This is limited to support only unambiguous expression paths. Of note,
+  // expression paths are not attempted if the expression contain either the
+  // arrow operator (`->`) or the subscript operator (`[]`). This is because
+  // both operators can be overloaded in C++, and could result in ambiguity in
+  // how the expression is handled. Additionally, `*` and `&` are not 
supported.
+  bool try_variable_path = expr.find_first_of("*&->[]") == StringRef::npos;
+  if (frame && try_variable_path) {
+Status status;
+VariableSP var_sp;
+auto valobj_sp = frame->GetValueForVariableExpressionPath(
+expr, eDynamicDontRunTarget,
+StackFrame::eExpressionPathOptionsAllowDirectIVarAccess, var_sp,
+status);
+if (valobj_sp && status.Success() && valobj_sp->GetError().Success()) {
   if (!suppress_result) {
 if (auto persisted_valobj = valobj_sp->Persist())
   valobj_sp = persisted_valobj;
diff --git a/lldb/test/API/commands/dwim-print/Makefile 
b/lldb/test/API/commands/dwim-print/Makefile
index 10495940055b63..8b20bcb050 100644
--- a/lldb/test/API/commands/dwim-print/Makefile
+++ b/lldb/test/API/commands/dwim-print/Makefile
@@ -1,3 +1,3 @@
-C_SOURCES := main.c
+CXX_SOURCES := main.cpp
 
 include Makefile.rules
diff --git a/lldb/test/API/commands/dwim-print/TestDWIMPrint.py 
b/lldb/test/API/commands/dwim-print/TestDWIMPrint.py
index b40924a182e37d..492d49f008a9e4 100644
--- a/lldb/test/API/commands/dwim-print/TestDWIMPrint.py
+++ b/lldb/test/API/commands/dwim-print/TestDWIMPrint.py
@@ -16,7 +16,7 @@ def _run_cmd(self, cmd: str) -> str:
 self.ci.HandleCommand(cmd, result)
 return result.GetOutput().rstrip()
 
-VAR_IDENT = re.compile(r"(?:\$\d+|\w+) = ")
+VAR_IDENT = re.compile(r"(?:\$\d+|[\w.]+) = ")
 
 def _strip_result_var(self, string: str) -> str:
 """
@@ -121,30 +121,39 @@ def test_empty_expression(self):
 def test_nested_values(self):
 """Test dwim-print with nested values (structs, etc)."""
 self.build()
-lldbutil.run_to_source_breakpoint(self, "break here", 
lldb.SBFileSpec("main.c"))
+lldbutil.run_to_source_breakpoint(
+self, "break here", lldb.SBFileSpec("main.cpp")
+)
 self.runCmd("settings set auto-one-line-summaries false")
 self._expect_cmd(f"dwim-print s", "frame variable")
 self._expect_cmd(f"dwim-print (struct Structure)s", "expression")
 
 def test_summary_strings(self):
-"""Test dwim-print with nested values (structs, etc)."""
+"""Test dwim-print with type summaries."""
 self.build()
-lldbutil.run_to_source_breakpoint(self, "break here", 
lldb.SBFileSpec("main.c"))
+lldbutil.run_to_source_breakpoint(
+self, "break here", lldb.SBFileSpec("main.cpp")
+)
 self.runCmd("settings set auto-one-line-summaries false")
 self.runCmd

[Lldb-commits] [lldb] [lldb] Avoid unnecessary regex check in dwim-print (PR #114608)

2024-11-23 Thread Dave Lee via lldb-commits


@@ -101,6 +101,10 @@ void CommandObjectDWIMPrint::DoExecute(StringRef command,
   // Add a hint if object description was requested, but no description
   // function was implemented.
   auto maybe_add_hint = [&](llvm::StringRef output) {
+static bool note_shown = false;
+if (note_shown)
+  return;

kastiglione wrote:

I don't see how call_once would work here. This lambda might be called once, or 
it might be called multiple times (even indefinitely).

https://github.com/llvm/llvm-project/pull/114608
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Update dwim-print to support limited variable expression paths (PR #117452)

2024-11-23 Thread Dave Lee via lldb-commits

https://github.com/kastiglione edited 
https://github.com/llvm/llvm-project/pull/117452
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits