[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