diff --git a/lldb/source/Commands/CommandObjectDWIMPrint.cpp b/lldb/source/Commands/CommandObjectDWIMPrint.cpp --- a/lldb/source/Commands/CommandObjectDWIMPrint.cpp +++ b/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; @@ -103,6 +109,7 @@ result.AppendMessageWithFormatv("note: ran `expression {0}{1}`", flags, expr); } + valobj_sp->Dump(result.GetOutputStream(), dump_options); result.SetStatus(eReturnStatusSuccessFinishResult); return true; diff --git a/lldb/source/Commands/CommandObjectExpression.h b/lldb/source/Commands/CommandObjectExpression.h --- a/lldb/source/Commands/CommandObjectExpression.h +++ b/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); diff --git a/lldb/source/Commands/CommandObjectExpression.cpp b/lldb/source/Commands/CommandObjectExpression.cpp --- a/lldb/source/Commands/CommandObjectExpression.cpp +++ b/lldb/source/Commands/CommandObjectExpression.cpp @@ -146,6 +146,21 @@ break; } + case 'C': { + // 'C' for "caching", since both 'P' and 'p' for persist are taken. Both 'R' + // flags are taken too. + 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 +189,7 @@ auto_apply_fixits = eLazyBoolCalculate; top_level = false; allow_jit = true; + suppress_persistent_result = false; } llvm::ArrayRef @@ -186,7 +202,9 @@ const Target &target, bool use_objc, lldb::DynamicValueType use_dynamic) { EvaluateExpressionOptions options; options.SetCoerceToId(use_objc); - if (m_verbosity == eLanguageRuntimeDescriptionDisplayVerbosityCompact) + if (suppress_persistent_result) + options.SetSuppressPersistentResult(true); + else if (m_verbosity == eLanguageRuntimeDescriptionDisplayVerbosityCompact) options.SetSuppressPersistentResult(use_objc); options.SetUnwindOnError(unwind_on_error); options.SetIgnoreBreakpoints(ignore_breakpoints); @@ -438,6 +456,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()); diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td --- a/lldb/source/Commands/Options.td +++ b/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", "C">, 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 { diff --git a/lldb/source/DataFormatters/ValueObjectPrinter.cpp b/lldb/source/DataFormatters/ValueObjectPrinter.cpp --- a/lldb/source/DataFormatters/ValueObjectPrinter.cpp +++ b/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->Write(" ", 1); + m_stream->Write(m_value.c_str(), m_value.length()); value_printed = true; } }