[Lldb-commits] [lldb] [lldb] Update dwim-print to support limited variable expression paths (PR #117452)
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)
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)
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)
@@ -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)
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