[Lldb-commits] [lldb] d160873 - [lldb] Add --gdb-format flag to dwim-print
Dave Lee via lldb-commits
lldb-commits at lists.llvm.org
Wed Feb 8 19:16:31 PST 2023
Author: Dave Lee
Date: 2023-02-08T19:16:20-08:00
New Revision: d160873c03aedfcd201851829aa423cc10ef593a
URL: https://github.com/llvm/llvm-project/commit/d160873c03aedfcd201851829aa423cc10ef593a
DIFF: https://github.com/llvm/llvm-project/commit/d160873c03aedfcd201851829aa423cc10ef593a.diff
LOG: [lldb] Add --gdb-format flag to dwim-print
Add support for the `--gdb-format`/`-G` flag to `dwim-print`.
The gdb-format flag allows users to alias `p` to `dwim-print`.
Differential Revision: https://reviews.llvm.org/D141425
Added:
Modified:
lldb/source/Commands/CommandObjectDWIMPrint.cpp
lldb/source/Commands/CommandObjectDWIMPrint.h
lldb/test/API/commands/dwim-print/TestDWIMPrint.py
Removed:
################################################################################
diff --git a/lldb/source/Commands/CommandObjectDWIMPrint.cpp b/lldb/source/Commands/CommandObjectDWIMPrint.cpp
index e15e723de5880..81da150aa2ddd 100644
--- a/lldb/source/Commands/CommandObjectDWIMPrint.cpp
+++ b/lldb/source/Commands/CommandObjectDWIMPrint.cpp
@@ -9,13 +9,19 @@
#include "CommandObjectDWIMPrint.h"
#include "lldb/Core/ValueObject.h"
+#include "lldb/DataFormatters/DumpValueObjectOptions.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandObject.h"
#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Interpreter/OptionGroupFormat.h"
+#include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Utility/ConstString.h"
+#include "lldb/lldb-defines.h"
#include "lldb/lldb-enumerations.h"
#include "lldb/lldb-forward.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/FormatVariadic.h"
using namespace llvm;
using namespace lldb;
@@ -26,28 +32,49 @@ CommandObjectDWIMPrint::CommandObjectDWIMPrint(CommandInterpreter &interpreter)
"Print a variable or expression.",
"dwim-print [<variable-name> | <expression>]",
eCommandProcessMustBePaused | eCommandTryTargetAPILock) {
+ m_option_group.Append(&m_format_options,
+ OptionGroupFormat::OPTION_GROUP_FORMAT |
+ OptionGroupFormat::OPTION_GROUP_GDB_FMT,
+ LLDB_OPT_SET_1);
+ m_option_group.Append(&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
+ m_option_group.Finalize();
}
-bool CommandObjectDWIMPrint::DoExecute(StringRef expr,
+Options *CommandObjectDWIMPrint::GetOptions() { return &m_option_group; }
+
+bool CommandObjectDWIMPrint::DoExecute(StringRef command,
CommandReturnObject &result) {
- // Ignore leading and trailing whitespace.
- expr = expr.trim();
+ m_option_group.NotifyOptionParsingStarting(&m_exe_ctx);
+ OptionsWithRaw args{command};
+ StringRef expr = args.GetRawPart();
- if (expr.empty()) {
+ if (args.HasArgs()) {
+ if (!ParseOptionsAndNotify(args.GetArgs(), result, m_option_group,
+ m_exe_ctx))
+ return false;
+ } else if (command.empty()) {
result.AppendErrorWithFormatv("'{0}' takes a variable or expression",
m_cmd_name);
return false;
}
-
auto verbosity = GetDebugger().GetDWIMPrintVerbosity();
+ DumpValueObjectOptions dump_options = m_varobj_options.GetAsDumpOptions(
+ eLanguageRuntimeDescriptionDisplayVerbosityFull,
+ m_format_options.GetFormat());
+
// 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 (verbosity == eDWIMPrintVerbosityFull)
- result.AppendMessageWithFormatv("note: ran `frame variable {0}`", expr);
- valobj_sp->Dump(result.GetOutputStream());
+ if (verbosity == eDWIMPrintVerbosityFull) {
+ StringRef flags;
+ if (args.HasArgs())
+ flags = args.GetArgString();
+ result.AppendMessageWithFormatv("note: ran `frame variable {0}{1}`",
+ flags, expr);
+ }
+ valobj_sp->Dump(result.GetOutputStream(), dump_options);
result.SetStatus(eReturnStatusSuccessFinishResult);
return true;
}
@@ -63,9 +90,14 @@ bool CommandObjectDWIMPrint::DoExecute(StringRef expr,
ValueObjectSP valobj_sp;
if (target.EvaluateExpression(expr, exe_scope, valobj_sp) ==
eExpressionCompleted) {
- if (verbosity != eDWIMPrintVerbosityNone)
- result.AppendMessageWithFormatv("note: ran `expression -- {0}`", expr);
- valobj_sp->Dump(result.GetOutputStream());
+ if (verbosity != eDWIMPrintVerbosityNone) {
+ StringRef flags;
+ if (args.HasArgs())
+ flags = args.GetArgStringWithDelimiter();
+ result.AppendMessageWithFormatv("note: ran `expression {0}{1}`", flags,
+ expr);
+ }
+ valobj_sp->Dump(result.GetOutputStream(), dump_options);
result.SetStatus(eReturnStatusSuccessFinishResult);
return true;
} else {
diff --git a/lldb/source/Commands/CommandObjectDWIMPrint.h b/lldb/source/Commands/CommandObjectDWIMPrint.h
index 1284949aed3ae..94daa85958b68 100644
--- a/lldb/source/Commands/CommandObjectDWIMPrint.h
+++ b/lldb/source/Commands/CommandObjectDWIMPrint.h
@@ -10,6 +10,9 @@
#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTDWIMPRINT_H
#include "lldb/Interpreter/CommandObject.h"
+#include "lldb/Interpreter/OptionGroupFormat.h"
+#include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
+#include "lldb/Interpreter/OptionValueFormat.h"
namespace lldb_private {
@@ -31,8 +34,14 @@ class CommandObjectDWIMPrint : public CommandObjectRaw {
~CommandObjectDWIMPrint() override = default;
+ Options *GetOptions() override;
+
private:
bool DoExecute(llvm::StringRef command, CommandReturnObject &result) override;
+
+ OptionGroupOptions m_option_group;
+ OptionGroupFormat m_format_options = lldb::eFormatDefault;
+ OptionGroupValueObjectDisplay m_varobj_options;
};
} // namespace lldb_private
diff --git a/lldb/test/API/commands/dwim-print/TestDWIMPrint.py b/lldb/test/API/commands/dwim-print/TestDWIMPrint.py
index 6b3266deaad86..c176e91be643d 100644
--- a/lldb/test/API/commands/dwim-print/TestDWIMPrint.py
+++ b/lldb/test/API/commands/dwim-print/TestDWIMPrint.py
@@ -27,22 +27,36 @@ def _mask_persistent_var(self, string: str) -> str:
before, after = self.PERSISTENT_VAR.split(string, maxsplit=1)
return re.escape(before) + r"\$\d+" + re.escape(after)
- def _expect_cmd(self, expr: str, base_cmd: str) -> None:
+ def _expect_cmd(
+ self,
+ dwim_cmd: str,
+ actual_cmd: str,
+ ) -> None:
"""Run dwim-print and verify the output against the expected command."""
- cmd = f"{base_cmd} {expr}"
- cmd_output = self._run_cmd(cmd)
+ # Resolve the dwim-print command to either `expression` or `frame variable`.
+ substitute_cmd = dwim_cmd.replace("dwim-print", actual_cmd, 1)
+ interp = self.dbg.GetCommandInterpreter()
+ result = lldb.SBCommandReturnObject()
+ interp.ResolveCommand(substitute_cmd, result)
+ self.assertTrue(result.Succeeded(), result.GetError())
+
+ resolved_cmd = result.GetOutput()
+ if actual_cmd == "frame variable":
+ resolved_cmd = resolved_cmd.replace(" -- ", " ", 1)
+
+ expected_output = self._run_cmd(resolved_cmd)
# Verify dwim-print chose the expected command.
self.runCmd("settings set dwim-print-verbosity full")
- substrs = [f"note: ran `{cmd}`"]
+ substrs = [f"note: ran `{resolved_cmd}`"]
patterns = []
- if base_cmd == "expression --" and self.PERSISTENT_VAR.search(cmd_output):
- patterns.append(self._mask_persistent_var(cmd_output))
+ if actual_cmd == "expression" and self.PERSISTENT_VAR.search(expected_output):
+ patterns.append(self._mask_persistent_var(expected_output))
else:
- substrs.append(cmd_output)
+ substrs.append(expected_output)
- self.expect(f"dwim-print {expr}", substrs=substrs, patterns=patterns)
+ self.expect(dwim_cmd, substrs=substrs, patterns=patterns)
def test_variables(self):
"""Test dwim-print with variables."""
@@ -50,7 +64,7 @@ def test_variables(self):
lldbutil.run_to_name_breakpoint(self, "main")
vars = ("argc", "argv")
for var in vars:
- self._expect_cmd(var, "frame variable")
+ self._expect_cmd(f"dwim-print {var}", "frame variable")
def test_variable_paths(self):
"""Test dwim-print with variable path expressions."""
@@ -58,7 +72,7 @@ def test_variable_paths(self):
lldbutil.run_to_name_breakpoint(self, "main")
exprs = ("&argc", "*argv", "argv[0]")
for expr in exprs:
- self._expect_cmd(expr, "expression --")
+ self._expect_cmd(f"dwim-print {expr}", "expression")
def test_expressions(self):
"""Test dwim-print with expressions."""
@@ -66,8 +80,26 @@ def test_expressions(self):
lldbutil.run_to_name_breakpoint(self, "main")
exprs = ("argc + 1", "(void)argc", "(int)abs(argc)")
for expr in exprs:
- self._expect_cmd(expr, "expression --")
+ self._expect_cmd(f"dwim-print {expr}", "expression")
def test_dummy_target_expressions(self):
"""Test dwim-print's ability to evaluate expressions without a target."""
- self._expect_cmd("1 + 2", "expression --")
+ self._expect_cmd("dwim-print 1 + 2", "expression")
+
+ def test_gdb_format(self):
+ self.build()
+ lldbutil.run_to_name_breakpoint(self, "main")
+ self._expect_cmd(f"dwim-print/x argc", "frame variable")
+ self._expect_cmd(f"dwim-print/x argc + 1", "expression")
+
+ def test_format_flags(self):
+ self.build()
+ lldbutil.run_to_name_breakpoint(self, "main")
+ self._expect_cmd(f"dwim-print -fx -- argc", "frame variable")
+ self._expect_cmd(f"dwim-print -fx -- argc + 1", "expression")
+
+ def test_display_flags(self):
+ self.build()
+ lldbutil.run_to_name_breakpoint(self, "main")
+ self._expect_cmd(f"dwim-print -T -- argc", "frame variable")
+ self._expect_cmd(f"dwim-print -T -- argc + 1", "expression")
More information about the lldb-commits
mailing list