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 lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits