kastiglione updated this revision to Diff 498394.
kastiglione added a comment.
Remove short option -C, leaving only --persistent-result
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D144230/new/
https://reviews.llvm.org/D144230
Files:
lldb/source/Commands/CommandObjectDWIMPrint.cpp
lldb/source/Commands/CommandObjectExpression.cpp
lldb/source/Commands/CommandObjectExpression.h
lldb/source/Commands/Options.td
lldb/source/DataFormatters/ValueObjectPrinter.cpp
lldb/test/API/commands/dwim-print/TestDWIMPrint.py
lldb/test/API/commands/expression/persistent_result/Makefile
lldb/test/API/commands/expression/persistent_result/TestPersistentResult.py
lldb/test/API/commands/expression/persistent_result/main.c
Index: lldb/test/API/commands/expression/persistent_result/main.c
===================================================================
--- /dev/null
+++ lldb/test/API/commands/expression/persistent_result/main.c
@@ -0,0 +1,4 @@
+int main() {
+ int i = 30;
+ return 0; // break here
+}
Index: lldb/test/API/commands/expression/persistent_result/TestPersistentResult.py
===================================================================
--- /dev/null
+++ lldb/test/API/commands/expression/persistent_result/TestPersistentResult.py
@@ -0,0 +1,37 @@
+"""
+Test controlling `expression` result variables are persistent.
+"""
+
+import lldb
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test.decorators import *
+from lldbsuite.test import lldbutil
+
+
+class TestCase(TestBase):
+ def setUp(self):
+ TestBase.setUp(self)
+ self.build()
+ lldbutil.run_to_source_breakpoint(self, "break here", lldb.SBFileSpec("main.c"))
+
+ def test_enable_persistent_result(self):
+ """Test explicitly enabling result variables persistence."""
+ self.expect("expression --persistent-result on -- i", substrs=["(int) $0 = 30"])
+ # Verify the lifetime of $0 extends beyond the `expression` it was created in.
+ self.expect("expression $0", substrs=["(int) $0 = 30"])
+
+ def test_disable_persistent_result(self):
+ """Test explicitly disabling persistent result variables."""
+ self.expect("expression --persistent-result off -- i", substrs=["(int) 30"])
+ # Verify a persistent result was not silently created.
+ self.expect("expression $0", error=True)
+
+ def test_expression_persists_result(self):
+ """Test `expression`'s default behavior is to persist a result variable."""
+ self.expect("expression i", substrs=["(int) $0 = 30"])
+ self.expect("expression $0", substrs=["(int) $0 = 30"])
+
+ def test_p_persists_result(self):
+ """Test `p` does persist a result variable."""
+ self.expect("p i", substrs=["(int) $0 = 30"])
+ self.expect("p $0", substrs=["(int) $0 = 30"])
Index: lldb/test/API/commands/expression/persistent_result/Makefile
===================================================================
--- /dev/null
+++ lldb/test/API/commands/expression/persistent_result/Makefile
@@ -0,0 +1,3 @@
+C_SOURCES := main.c
+
+include Makefile.rules
Index: lldb/test/API/commands/dwim-print/TestDWIMPrint.py
===================================================================
--- lldb/test/API/commands/dwim-print/TestDWIMPrint.py
+++ lldb/test/API/commands/dwim-print/TestDWIMPrint.py
@@ -16,7 +16,8 @@
self.ci.HandleCommand(cmd, result)
return result.GetOutput().rstrip()
- PERSISTENT_VAR = re.compile(r"\$\d+")
+ VAR_IDENT_RAW = r"(?:\$\d+|\w+) = "
+ VAR_IDENT = re.compile(VAR_IDENT_RAW)
def _mask_persistent_var(self, string: str) -> str:
"""
@@ -24,8 +25,9 @@
that matches any persistent result (r'\$\d+'). The returned string can
be matched against other `expression` results.
"""
- before, after = self.PERSISTENT_VAR.split(string, maxsplit=1)
- return re.escape(before) + r"\$\d+" + re.escape(after)
+ before, after = self.VAR_IDENT.split(string, maxsplit=1)
+ # Support either a frame variable (\w+) or a persistent result (\$\d+).
+ return re.escape(before) + self.VAR_IDENT_RAW + re.escape(after)
def _expect_cmd(
self,
@@ -51,7 +53,7 @@
substrs = [f"note: ran `{resolved_cmd}`"]
patterns = []
- if actual_cmd == "expression" and self.PERSISTENT_VAR.search(expected_output):
+ if self.VAR_IDENT.search(expected_output):
patterns.append(self._mask_persistent_var(expected_output))
else:
substrs.append(expected_output)
Index: lldb/source/DataFormatters/ValueObjectPrinter.cpp
===================================================================
--- lldb/source/DataFormatters/ValueObjectPrinter.cpp
+++ lldb/source/DataFormatters/ValueObjectPrinter.cpp
@@ -425,7 +425,9 @@
if (m_options.m_hide_pointer_value &&
IsPointerValue(m_valobj->GetCompilerType())) {
} else {
- m_stream->Printf(" %s", m_value.c_str());
+ if (!m_options.m_hide_name)
+ m_stream->PutChar(' ');
+ m_stream->PutCString(m_value);
value_printed = true;
}
}
Index: lldb/source/Commands/Options.td
===================================================================
--- lldb/source/Commands/Options.td
+++ lldb/source/Commands/Options.td
@@ -386,6 +386,11 @@
Arg<"Boolean">,
Desc<"Controls whether the expression can fall back to being JITted if it's "
"not supported by the interpreter (defaults to true).">;
+ def persistent_result : Option<"persistent-result", "\\x01">, Groups<[1,2]>,
+ Arg<"Boolean">,
+ Desc<"Persist expression result in a variable for subsequent use. "
+ "Expression results will be labeled with $-prefixed variables, e.g. $0, "
+ "$1, etc. Defaults to true.">;
}
let Command = "frame diag" in {
Index: lldb/source/Commands/CommandObjectExpression.h
===================================================================
--- lldb/source/Commands/CommandObjectExpression.h
+++ lldb/source/Commands/CommandObjectExpression.h
@@ -53,6 +53,7 @@
lldb::LanguageType language;
LanguageRuntimeDescriptionDisplayVerbosity m_verbosity;
LazyBool auto_apply_fixits;
+ bool suppress_persistent_result;
};
CommandObjectExpression(CommandInterpreter &interpreter);
Index: lldb/source/Commands/CommandObjectExpression.cpp
===================================================================
--- lldb/source/Commands/CommandObjectExpression.cpp
+++ lldb/source/Commands/CommandObjectExpression.cpp
@@ -146,6 +146,19 @@
break;
}
+ case '\x01': {
+ bool success;
+ bool persist_result =
+ OptionArgParser::ToBoolean(option_arg, true, &success);
+ if (success)
+ suppress_persistent_result = !persist_result;
+ else
+ error.SetErrorStringWithFormat(
+ "could not convert \"%s\" to a boolean value.",
+ option_arg.str().c_str());
+ break;
+ }
+
default:
llvm_unreachable("Unimplemented option");
}
@@ -174,6 +187,7 @@
auto_apply_fixits = eLazyBoolCalculate;
top_level = false;
allow_jit = true;
+ suppress_persistent_result = false;
}
llvm::ArrayRef<OptionDefinition>
@@ -186,7 +200,9 @@
const Target &target, const OptionGroupValueObjectDisplay &display_opts) {
EvaluateExpressionOptions options;
options.SetCoerceToId(display_opts.use_objc);
- if (m_verbosity == eLanguageRuntimeDescriptionDisplayVerbosityCompact)
+ if (suppress_persistent_result)
+ options.SetSuppressPersistentResult(true);
+ else if (m_verbosity == eLanguageRuntimeDescriptionDisplayVerbosityCompact)
options.SetSuppressPersistentResult(display_opts.use_objc);
options.SetUnwindOnError(unwind_on_error);
options.SetIgnoreBreakpoints(ignore_breakpoints);
@@ -437,6 +453,8 @@
DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions(
m_command_options.m_verbosity, format));
+ if (m_command_options.suppress_persistent_result)
+ options.SetHideName(true);
options.SetVariableFormatDisplayLanguage(
result_valobj_sp->GetPreferredDisplayLanguage());
Index: lldb/source/Commands/CommandObjectDWIMPrint.cpp
===================================================================
--- lldb/source/Commands/CommandObjectDWIMPrint.cpp
+++ lldb/source/Commands/CommandObjectDWIMPrint.cpp
@@ -64,11 +64,16 @@
DumpValueObjectOptions dump_options = m_varobj_options.GetAsDumpOptions(
m_expr_options.m_verbosity, m_format_options.GetFormat());
+ if (m_expr_options.suppress_persistent_result)
+ dump_options.SetHideName(true);
// First, try `expr` as the name of a frame variable.
if (StackFrame *frame = m_exe_ctx.GetFramePtr()) {
auto valobj_sp = frame->FindVariable(ConstString(expr));
if (valobj_sp && valobj_sp->GetError().Success()) {
+ if (!m_expr_options.suppress_persistent_result)
+ valobj_sp = valobj_sp->Persist();
+
if (verbosity == eDWIMPrintVerbosityFull) {
StringRef flags;
if (args.HasArgs())
@@ -76,6 +81,7 @@
result.AppendMessageWithFormatv("note: ran `frame variable {0}{1}`",
flags, expr);
}
+
valobj_sp->Dump(result.GetOutputStream(), dump_options);
result.SetStatus(eReturnStatusSuccessFinishResult);
return true;
@@ -102,6 +108,7 @@
result.AppendMessageWithFormatv("note: ran `expression {0}{1}`", flags,
expr);
}
+
valobj_sp->Dump(result.GetOutputStream(), dump_options);
result.SetStatus(eReturnStatusSuccessFinishResult);
return true;
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits