[Lldb-commits] [lldb] [lldb] Add repeat command for `frame variable` (PR #194195)

Dave Lee via lldb-commits lldb-commits at lists.llvm.org
Tue Apr 28 12:54:07 PDT 2026


https://github.com/kastiglione updated https://github.com/llvm/llvm-project/pull/194195

>From 584945c03da75c9e31e4850ff2dcef2abb7e96ee Mon Sep 17 00:00:00 2001
From: Dave Lee <davelee.com at gmail.com>
Date: Sat, 25 Apr 2026 16:39:11 -0700
Subject: [PATCH 1/8] [lldb] Add repeat command for `frame variable`

---
 lldb/source/Commands/CommandObjectFrame.cpp   | 28 +++++++++++++++++
 .../API/commands/frame/var/repeat/Makefile    |  3 ++
 .../frame/var/repeat/TestFrameVarRepeat.py    | 31 +++++++++++++++++++
 .../API/commands/frame/var/repeat/main.cpp    | 20 ++++++++++++
 4 files changed, 82 insertions(+)
 create mode 100644 lldb/test/API/commands/frame/var/repeat/Makefile
 create mode 100644 lldb/test/API/commands/frame/var/repeat/TestFrameVarRepeat.py
 create mode 100644 lldb/test/API/commands/frame/var/repeat/main.cpp

diff --git a/lldb/source/Commands/CommandObjectFrame.cpp b/lldb/source/Commands/CommandObjectFrame.cpp
index 2a726f8e0fd8f..88e8e9e32cff1 100644
--- a/lldb/source/Commands/CommandObjectFrame.cpp
+++ b/lldb/source/Commands/CommandObjectFrame.cpp
@@ -32,6 +32,7 @@
 #include "lldb/Utility/ValueType.h"
 #include "lldb/ValueObject/ValueObject.h"
 #include "lldb/lldb-enumerations.h"
+#include "llvm/ADT/StringRef.h"
 
 #include <memory>
 #include <optional>
@@ -435,6 +436,33 @@ may even involve JITing and running code in the target program.)");
 
   Options *GetOptions() override { return &m_option_group; }
 
+  // `frame variable` repeats by incrementing the printing depth. When the depth
+  // is too shallow, hitting enter a few times will quickly expand the data.
+  std::optional<std::string> GetRepeatCommand(Args &current_command_args,
+                                              uint32_t index) override {
+    uint32_t new_depth = m_varobj_options.max_depth + 1;
+    std::string cmd;
+    llvm::raw_string_ostream os(cmd);
+    bool skip_next = false;
+    for (const auto &entry : current_command_args) {
+      if (skip_next) {
+        skip_next = false;
+        continue;
+      }
+
+      llvm::StringRef arg = entry.ref();
+      if (arg == "--depth" || arg == "-D") {
+        skip_next = true;
+        os << " " << arg << " " << new_depth;
+      } else if (arg.starts_with("-D")) {
+        os << "-D" << new_depth;
+      } else {
+        os << " " << arg;
+      }
+    }
+    return cmd;
+  }
+
 protected:
   llvm::StringRef GetScopeString(VariableSP var_sp) {
     if (!var_sp)
diff --git a/lldb/test/API/commands/frame/var/repeat/Makefile b/lldb/test/API/commands/frame/var/repeat/Makefile
new file mode 100644
index 0000000000000..99998b20bcb05
--- /dev/null
+++ b/lldb/test/API/commands/frame/var/repeat/Makefile
@@ -0,0 +1,3 @@
+CXX_SOURCES := main.cpp
+
+include Makefile.rules
diff --git a/lldb/test/API/commands/frame/var/repeat/TestFrameVarRepeat.py b/lldb/test/API/commands/frame/var/repeat/TestFrameVarRepeat.py
new file mode 100644
index 0000000000000..89d0f6feec529
--- /dev/null
+++ b/lldb/test/API/commands/frame/var/repeat/TestFrameVarRepeat.py
@@ -0,0 +1,31 @@
+import lldb
+from lldbsuite.test.lldbtest import TestBase
+from lldbsuite.test import lldbutil
+
+
+class TestCase(TestBase):
+    def test(self):
+        """Test that repeating 'frame variable' increments --depth."""
+        self.build()
+        lldbutil.run_to_source_breakpoint(
+            self, "break here", lldb.SBFileSpec("main.cpp")
+        )
+
+        # Start with --depth 0 showing a, but not b.
+        self.expect(
+            "frame variable --depth 0 a",
+            inHistory=True,
+            patterns=[r"\(A\) a = {", r"(?!.*b = {)"],
+        )
+
+        # First repeat: --depth 1 showing b, but not c.
+        self.expect("", patterns=["b = {", "(?!.*c = {)"])
+
+        # Second repeat: --depth 2, showing c, but not d.
+        self.expect("", patterns=["c = {", "(?!.*d = {)"])
+
+        # Third repeat: --depth 3, showing d, but not value.
+        self.expect("", patterns=["d = {", "(?!.*value = 42)"])
+
+        # Fourth repeat: --depth 4, showing value, the deepest value.
+        self.expect("", substrs=["value = 42"])
diff --git a/lldb/test/API/commands/frame/var/repeat/main.cpp b/lldb/test/API/commands/frame/var/repeat/main.cpp
new file mode 100644
index 0000000000000..78225fad724eb
--- /dev/null
+++ b/lldb/test/API/commands/frame/var/repeat/main.cpp
@@ -0,0 +1,20 @@
+struct D {
+  int value = 42;
+};
+
+struct C {
+  D d;
+};
+
+struct B {
+  C c;
+};
+
+struct A {
+  B b;
+};
+
+int main() {
+  A a;
+  return 0; // break here
+}

>From 6ff75eda18343f2b45823d9e50ea6331914e9738 Mon Sep 17 00:00:00 2001
From: Dave Lee <davelee.com at gmail.com>
Date: Mon, 27 Apr 2026 09:41:37 -0700
Subject: [PATCH 2/8] Handle incrementing of default depth

---
 lldb/source/Commands/CommandObjectFrame.cpp   | 10 ++++-
 .../frame/var/repeat/TestFrameVarRepeat.py    | 42 +++++++++++++------
 .../API/commands/frame/var/repeat/main.cpp    | 10 ++++-
 3 files changed, 48 insertions(+), 14 deletions(-)

diff --git a/lldb/source/Commands/CommandObjectFrame.cpp b/lldb/source/Commands/CommandObjectFrame.cpp
index 88e8e9e32cff1..c5e1f7abf5bf1 100644
--- a/lldb/source/Commands/CommandObjectFrame.cpp
+++ b/lldb/source/Commands/CommandObjectFrame.cpp
@@ -440,9 +440,11 @@ may even involve JITing and running code in the target program.)");
   // is too shallow, hitting enter a few times will quickly expand the data.
   std::optional<std::string> GetRepeatCommand(Args &current_command_args,
                                               uint32_t index) override {
-    uint32_t new_depth = m_varobj_options.max_depth + 1;
     std::string cmd;
     llvm::raw_string_ostream os(cmd);
+
+    uint32_t new_depth = m_varobj_options.max_depth + 1;
+    bool has_depth_option = false;
     bool skip_next = false;
     for (const auto &entry : current_command_args) {
       if (skip_next) {
@@ -454,12 +456,18 @@ may even involve JITing and running code in the target program.)");
       if (arg == "--depth" || arg == "-D") {
         skip_next = true;
         os << " " << arg << " " << new_depth;
+        has_depth_option = true;
       } else if (arg.starts_with("-D")) {
         os << "-D" << new_depth;
+        has_depth_option = true;
       } else {
         os << " " << arg;
       }
     }
+
+    if (!has_depth_option)
+      os << " --depth " << new_depth;
+
     return cmd;
   }
 
diff --git a/lldb/test/API/commands/frame/var/repeat/TestFrameVarRepeat.py b/lldb/test/API/commands/frame/var/repeat/TestFrameVarRepeat.py
index 89d0f6feec529..bfbd80bfb5c27 100644
--- a/lldb/test/API/commands/frame/var/repeat/TestFrameVarRepeat.py
+++ b/lldb/test/API/commands/frame/var/repeat/TestFrameVarRepeat.py
@@ -4,28 +4,46 @@
 
 
 class TestCase(TestBase):
-    def test(self):
+
+    def test_explicit_depth(self):
         """Test that repeating 'frame variable' increments --depth."""
         self.build()
         lldbutil.run_to_source_breakpoint(
             self, "break here", lldb.SBFileSpec("main.cpp")
         )
 
-        # Start with --depth 0 showing a, but not b.
+        # Start with --depth 2 showing a, b, and c, but but not d.
         self.expect(
-            "frame variable --depth 0 a",
+            "frame variable --depth 2 a",
             inHistory=True,
-            patterns=[r"\(A\) a = {", r"(?!.*b = {)"],
+            patterns=[r"\(A\) a = {", "b = {", "c = {", r"(?!.*d = {)"],
         )
 
-        # First repeat: --depth 1 showing b, but not c.
-        self.expect("", patterns=["b = {", "(?!.*c = {)"])
+        # First repeat: --depth 4, showing d, but not e.
+        self.expect("", patterns=["d = {", "(?!.*e = {)"])
+
+        # Second repeat: --depth 5, showing e, but not f.
+        self.expect("", patterns=["e = {", "(?!.*f = {)"])
+
+        # Third repeat: --depth 6, showing d, but not f.
+        self.expect("", patterns=["e = {", "(?!.*leaf = 42)"])
 
-        # Second repeat: --depth 2, showing c, but not d.
-        self.expect("", patterns=["c = {", "(?!.*d = {)"])
+        # Fourth repeat: --depth 7, showing leaf, the deepest child.
+        self.expect("", substrs=["leaf = 42"])
 
-        # Third repeat: --depth 3, showing d, but not value.
-        self.expect("", patterns=["d = {", "(?!.*value = 42)"])
+    def test_default_depth(self):
+        """Test that repeating 'frame variable' adds a --depth option."""
+        self.build()
+        lldbutil.run_to_source_breakpoint(
+            self, "break here", lldb.SBFileSpec("main.cpp")
+        )
+
+        # Default depth shows f but not leaf.
+        self.expect(
+            "frame variable a",
+            inHistory=True,
+            patterns=[r"f = \{...\}", r"(?!.*leaf = 42)"],
+        )
 
-        # Fourth repeat: --depth 4, showing value, the deepest value.
-        self.expect("", substrs=["value = 42"])
+        # Repeat
+        self.expect("", substrs=["leaf = 42"])
diff --git a/lldb/test/API/commands/frame/var/repeat/main.cpp b/lldb/test/API/commands/frame/var/repeat/main.cpp
index 78225fad724eb..7f95251776b62 100644
--- a/lldb/test/API/commands/frame/var/repeat/main.cpp
+++ b/lldb/test/API/commands/frame/var/repeat/main.cpp
@@ -1,5 +1,12 @@
+struct F {
+  int leaf = 42;
+};
+
+struct E {
+  F f;
+};
 struct D {
-  int value = 42;
+  E e;
 };
 
 struct C {
@@ -16,5 +23,6 @@ struct A {
 
 int main() {
   A a;
+  (void)a;
   return 0; // break here
 }

>From 7cfb14e953b78c099db0d6735d9d59ddf48ebea8 Mon Sep 17 00:00:00 2001
From: Dave Lee <davelee.com at gmail.com>
Date: Mon, 27 Apr 2026 09:44:41 -0700
Subject: [PATCH 3/8] Fixes to test

---
 .../frame/var/repeat/TestFrameVarRepeat.py         | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/lldb/test/API/commands/frame/var/repeat/TestFrameVarRepeat.py b/lldb/test/API/commands/frame/var/repeat/TestFrameVarRepeat.py
index bfbd80bfb5c27..de8412085b2ff 100644
--- a/lldb/test/API/commands/frame/var/repeat/TestFrameVarRepeat.py
+++ b/lldb/test/API/commands/frame/var/repeat/TestFrameVarRepeat.py
@@ -12,23 +12,23 @@ def test_explicit_depth(self):
             self, "break here", lldb.SBFileSpec("main.cpp")
         )
 
-        # Start with --depth 2 showing a, b, and c, but but not d.
+        # Start with --depth 2, shows a, b, and c, but but not d.
         self.expect(
             "frame variable --depth 2 a",
             inHistory=True,
             patterns=[r"\(A\) a = {", "b = {", "c = {", r"(?!.*d = {)"],
         )
 
-        # First repeat: --depth 4, showing d, but not e.
+        # First repeat: shows d, but not e.
         self.expect("", patterns=["d = {", "(?!.*e = {)"])
 
-        # Second repeat: --depth 5, showing e, but not f.
+        # Second repeat: shows e, but not f.
         self.expect("", patterns=["e = {", "(?!.*f = {)"])
 
-        # Third repeat: --depth 6, showing d, but not f.
-        self.expect("", patterns=["e = {", "(?!.*leaf = 42)"])
+        # Third repeat: shows f, but not leaf.
+        self.expect("", patterns=["f = {", "(?!.*leaf = 42)"])
 
-        # Fourth repeat: --depth 7, showing leaf, the deepest child.
+        # Fourth repeat: shows leaf, the deepest child.
         self.expect("", substrs=["leaf = 42"])
 
     def test_default_depth(self):
@@ -45,5 +45,5 @@ def test_default_depth(self):
             patterns=[r"f = \{...\}", r"(?!.*leaf = 42)"],
         )
 
-        # Repeat
+        # Repeat to show leaf.
         self.expect("", substrs=["leaf = 42"])

>From cea3e6d8e5351fdc246a34fdf6cf863b62e262a7 Mon Sep 17 00:00:00 2001
From: Dave Lee <davelee.com at gmail.com>
Date: Mon, 27 Apr 2026 09:46:02 -0700
Subject: [PATCH 4/8] formatting

---
 lldb/test/API/commands/frame/var/repeat/TestFrameVarRepeat.py | 1 -
 1 file changed, 1 deletion(-)

diff --git a/lldb/test/API/commands/frame/var/repeat/TestFrameVarRepeat.py b/lldb/test/API/commands/frame/var/repeat/TestFrameVarRepeat.py
index de8412085b2ff..755dd6e28e0fa 100644
--- a/lldb/test/API/commands/frame/var/repeat/TestFrameVarRepeat.py
+++ b/lldb/test/API/commands/frame/var/repeat/TestFrameVarRepeat.py
@@ -4,7 +4,6 @@
 
 
 class TestCase(TestBase):
-
     def test_explicit_depth(self):
         """Test that repeating 'frame variable' increments --depth."""
         self.build()

>From daae02de0626c6432ee2a5d10ee9f00b45c0a598 Mon Sep 17 00:00:00 2001
From: Dave Lee <davelee.com at gmail.com>
Date: Mon, 27 Apr 2026 10:48:07 -0700
Subject: [PATCH 5/8] Use GetQuotedCommandString to construct repeat command
 string

---
 lldb/source/Commands/CommandObjectFrame.cpp | 29 +++++++++++++--------
 1 file changed, 18 insertions(+), 11 deletions(-)

diff --git a/lldb/source/Commands/CommandObjectFrame.cpp b/lldb/source/Commands/CommandObjectFrame.cpp
index c5e1f7abf5bf1..e5522374abe35 100644
--- a/lldb/source/Commands/CommandObjectFrame.cpp
+++ b/lldb/source/Commands/CommandObjectFrame.cpp
@@ -32,6 +32,7 @@
 #include "lldb/Utility/ValueType.h"
 #include "lldb/ValueObject/ValueObject.h"
 #include "lldb/lldb-enumerations.h"
+#include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/StringRef.h"
 
 #include <memory>
@@ -440,11 +441,15 @@ may even involve JITing and running code in the target program.)");
   // is too shallow, hitting enter a few times will quickly expand the data.
   std::optional<std::string> GetRepeatCommand(Args &current_command_args,
                                               uint32_t index) override {
-    std::string cmd;
-    llvm::raw_string_ostream os(cmd);
-
-    uint32_t new_depth = m_varobj_options.max_depth + 1;
+    Args repeat_args;
     bool has_depth_option = false;
+    auto new_depth = m_varobj_options.max_depth + 1;
+    auto increment_depth_option = [&]() {
+      repeat_args.AppendArgument("--depth");
+      repeat_args.AppendArgument(llvm::utostr(new_depth));
+      has_depth_option = true;
+    };
+
     bool skip_next = false;
     for (const auto &entry : current_command_args) {
       if (skip_next) {
@@ -455,20 +460,22 @@ may even involve JITing and running code in the target program.)");
       llvm::StringRef arg = entry.ref();
       if (arg == "--depth" || arg == "-D") {
         skip_next = true;
-        os << " " << arg << " " << new_depth;
-        has_depth_option = true;
+        increment_depth_option();
       } else if (arg.starts_with("-D")) {
-        os << "-D" << new_depth;
-        has_depth_option = true;
+        increment_depth_option();
       } else {
-        os << " " << arg;
+        repeat_args.AppendArgument(arg);
       }
     }
 
     if (!has_depth_option)
-      os << " --depth " << new_depth;
+      // Default depth was used.
+      increment_depth_option();
 
-    return cmd;
+    std::string repeat_command;
+    if (!repeat_args.GetQuotedCommandString(repeat_command))
+      return std::nullopt;
+    return repeat_command;
   }
 
 protected:

>From 81cf446223d4195a95d7b5171b520ae15aacc70e Mon Sep 17 00:00:00 2001
From: Dave Lee <davelee.com at gmail.com>
Date: Tue, 28 Apr 2026 10:17:13 -0700
Subject: [PATCH 6/8] Reimplement to workaround unparsed options

---
 lldb/source/Commands/CommandObjectFrame.cpp | 56 ++++++++++++++-------
 1 file changed, 37 insertions(+), 19 deletions(-)

diff --git a/lldb/source/Commands/CommandObjectFrame.cpp b/lldb/source/Commands/CommandObjectFrame.cpp
index e5522374abe35..73e473f630b37 100644
--- a/lldb/source/Commands/CommandObjectFrame.cpp
+++ b/lldb/source/Commands/CommandObjectFrame.cpp
@@ -442,35 +442,53 @@ may even involve JITing and running code in the target program.)");
   std::optional<std::string> GetRepeatCommand(Args &current_command_args,
                                               uint32_t index) override {
     Args repeat_args;
-    bool has_depth_option = false;
-    auto new_depth = m_varobj_options.max_depth + 1;
-    auto increment_depth_option = [&]() {
-      repeat_args.AppendArgument("--depth");
-      repeat_args.AppendArgument(llvm::utostr(new_depth));
-      has_depth_option = true;
+    auto increment_option = [&](llvm::StringRef option) {
+      uint32_t num;
+      bool failed = option.getAsInteger(10, num);
+      if (failed)
+        return false;
+      repeat_args.AppendArgument(llvm::utostr(num + 1));
+      return true;
     };
 
-    bool skip_next = false;
+    bool has_depth_option = false;
+    bool increment_next_arg = false;
     for (const auto &entry : current_command_args) {
-      if (skip_next) {
-        skip_next = false;
-        continue;
+      llvm::StringRef arg = entry.ref();
+
+      if (increment_next_arg) {
+        increment_next_arg = false;
+        if (increment_option(arg))
+          continue;
       }
 
-      llvm::StringRef arg = entry.ref();
       if (arg == "--depth" || arg == "-D") {
-        skip_next = true;
-        increment_depth_option();
-      } else if (arg.starts_with("-D")) {
-        increment_depth_option();
-      } else {
         repeat_args.AppendArgument(arg);
+        increment_next_arg = true;
+        has_depth_option = true;
+        continue;
+      }
+      if (arg.consume_front("-D") && increment_option(arg)) {
+        has_depth_option = true;
+        continue;
       }
+
+      repeat_args.AppendArgument(arg);
     }
 
-    if (!has_depth_option)
-      // Default depth was used.
-      increment_depth_option();
+    if (!has_depth_option) {
+      // Access the default max-depth from the target. This is because
+      // GetRepeatCommand is called before ParseOptions, which is when
+      // m_varobj_options.max_depth becomes assigned.
+      if (auto target_sp = GetDebugger().GetSelectedTarget()) {
+        auto [default_depth, _] =
+            target_sp->GetMaximumDepthOfChildrenToDisplay();
+        // Insert the depth after `frame variable`, before positional args.
+        assert(repeat_args[0].ref() == "frame" && "expects resolved command");
+        repeat_args.InsertArgumentAtIndex(2, "--depth");
+        repeat_args.InsertArgumentAtIndex(3, llvm::utostr(default_depth + 1));
+      }
+    }
 
     std::string repeat_command;
     if (!repeat_args.GetQuotedCommandString(repeat_command))

>From d943c185de403b5cf5cb5bee4778ebb1de0a690c Mon Sep 17 00:00:00 2001
From: Dave Lee <davelee.com at gmail.com>
Date: Tue, 28 Apr 2026 10:37:50 -0700
Subject: [PATCH 7/8] Fix handling of -D<N>, and test

---
 lldb/source/Commands/CommandObjectFrame.cpp   | 21 ++++++++++++-------
 .../frame/var/repeat/TestFrameVarRepeat.py    |  6 +++++-
 2 files changed, 18 insertions(+), 9 deletions(-)

diff --git a/lldb/source/Commands/CommandObjectFrame.cpp b/lldb/source/Commands/CommandObjectFrame.cpp
index 73e473f630b37..6bc642dc45216 100644
--- a/lldb/source/Commands/CommandObjectFrame.cpp
+++ b/lldb/source/Commands/CommandObjectFrame.cpp
@@ -442,13 +442,13 @@ may even involve JITing and running code in the target program.)");
   std::optional<std::string> GetRepeatCommand(Args &current_command_args,
                                               uint32_t index) override {
     Args repeat_args;
-    auto increment_option = [&](llvm::StringRef option) {
+    auto increment_option =
+        [&](llvm::StringRef option) -> std::optional<std::string> {
       uint32_t num;
       bool failed = option.getAsInteger(10, num);
       if (failed)
-        return false;
-      repeat_args.AppendArgument(llvm::utostr(num + 1));
-      return true;
+        return std::nullopt;
+      return llvm::utostr(num + 1);
     };
 
     bool has_depth_option = false;
@@ -458,8 +458,10 @@ may even involve JITing and running code in the target program.)");
 
       if (increment_next_arg) {
         increment_next_arg = false;
-        if (increment_option(arg))
+        if (auto maybe_opt = increment_option(arg)) {
+          repeat_args.AppendArgument(*maybe_opt);
           continue;
+        }
       }
 
       if (arg == "--depth" || arg == "-D") {
@@ -468,9 +470,12 @@ may even involve JITing and running code in the target program.)");
         has_depth_option = true;
         continue;
       }
-      if (arg.consume_front("-D") && increment_option(arg)) {
-        has_depth_option = true;
-        continue;
+      if (arg.consume_front("-D")) {
+        if (auto maybe_opt = increment_option(arg)) {
+          repeat_args.AppendArgument(llvm::formatv("-D{0}", *maybe_opt).str());
+          has_depth_option = true;
+          continue;
+        }
       }
 
       repeat_args.AppendArgument(arg);
diff --git a/lldb/test/API/commands/frame/var/repeat/TestFrameVarRepeat.py b/lldb/test/API/commands/frame/var/repeat/TestFrameVarRepeat.py
index 755dd6e28e0fa..b55fb00fb971e 100644
--- a/lldb/test/API/commands/frame/var/repeat/TestFrameVarRepeat.py
+++ b/lldb/test/API/commands/frame/var/repeat/TestFrameVarRepeat.py
@@ -10,10 +10,14 @@ def test_explicit_depth(self):
         lldbutil.run_to_source_breakpoint(
             self, "break here", lldb.SBFileSpec("main.cpp")
         )
+        self.do_test("--depth ")
+        self.do_test("-D ")
+        self.do_test("-D")
 
+    def do_test(self, depth_option):
         # Start with --depth 2, shows a, b, and c, but but not d.
         self.expect(
-            "frame variable --depth 2 a",
+            f"frame variable {depth_option}2 a",
             inHistory=True,
             patterns=[r"\(A\) a = {", "b = {", "c = {", r"(?!.*d = {)"],
         )

>From 37106d0634dd91cf75d8eb9bb79d097b4538a440 Mon Sep 17 00:00:00 2001
From: Dave Lee <davelee.com at gmail.com>
Date: Tue, 28 Apr 2026 12:53:29 -0700
Subject: [PATCH 8/8] Support unique prefix of --depth

---
 lldb/source/Commands/CommandObjectFrame.cpp              | 9 ++++++++-
 .../API/commands/frame/var/repeat/TestFrameVarRepeat.py  | 1 +
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/lldb/source/Commands/CommandObjectFrame.cpp b/lldb/source/Commands/CommandObjectFrame.cpp
index 6bc642dc45216..b1cc6c42a04fc 100644
--- a/lldb/source/Commands/CommandObjectFrame.cpp
+++ b/lldb/source/Commands/CommandObjectFrame.cpp
@@ -441,6 +441,8 @@ may even involve JITing and running code in the target program.)");
   // is too shallow, hitting enter a few times will quickly expand the data.
   std::optional<std::string> GetRepeatCommand(Args &current_command_args,
                                               uint32_t index) override {
+    llvm::StringRef depth_opt = "--depth";
+
     Args repeat_args;
     auto increment_option =
         [&](llvm::StringRef option) -> std::optional<std::string> {
@@ -456,6 +458,11 @@ may even involve JITing and running code in the target program.)");
     for (const auto &entry : current_command_args) {
       llvm::StringRef arg = entry.ref();
 
+      if (arg == "-" || arg == "--") {
+        repeat_args.AppendArgument(arg);
+        continue;
+      }
+
       if (increment_next_arg) {
         increment_next_arg = false;
         if (auto maybe_opt = increment_option(arg)) {
@@ -464,7 +471,7 @@ may even involve JITing and running code in the target program.)");
         }
       }
 
-      if (arg == "--depth" || arg == "-D") {
+      if (depth_opt.starts_with(arg) || arg == "-D") {
         repeat_args.AppendArgument(arg);
         increment_next_arg = true;
         has_depth_option = true;
diff --git a/lldb/test/API/commands/frame/var/repeat/TestFrameVarRepeat.py b/lldb/test/API/commands/frame/var/repeat/TestFrameVarRepeat.py
index b55fb00fb971e..97ca35cb47416 100644
--- a/lldb/test/API/commands/frame/var/repeat/TestFrameVarRepeat.py
+++ b/lldb/test/API/commands/frame/var/repeat/TestFrameVarRepeat.py
@@ -11,6 +11,7 @@ def test_explicit_depth(self):
             self, "break here", lldb.SBFileSpec("main.cpp")
         )
         self.do_test("--depth ")
+        self.do_test("--de ")
         self.do_test("-D ")
         self.do_test("-D")
 



More information about the lldb-commits mailing list