kastiglione updated this revision to Diff 498390.
kastiglione added a comment.

fix Makefile


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.m
+
+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", "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 {
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,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<OptionDefinition>
@@ -186,7 +202,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 +455,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

Reply via email to