augusto2112 created this revision.
augusto2112 added reviewers: kastiglione, jingham.
Herald added a project: All.
augusto2112 requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

Lots of users use "po" as their default print command. If the type
doesn't implement the description function the output is often not what
the user wants. Print a hint telling the user that they might prefer
using "p" instead.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D153489

Files:
  lldb/source/Commands/CommandObjectDWIMPrint.cpp
  lldb/source/Commands/CommandObjectDWIMPrint.h
  lldb/source/Commands/CommandObjectExpression.cpp
  lldb/source/Commands/CommandObjectFrame.cpp

Index: lldb/source/Commands/CommandObjectFrame.cpp
===================================================================
--- lldb/source/Commands/CommandObjectFrame.cpp
+++ lldb/source/Commands/CommandObjectFrame.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 #include "CommandObjectFrame.h"
+
+#include "CommandObjectDWIMPrint.h"
 #include "lldb/Core/Debugger.h"
 #include "lldb/Core/ValueObject.h"
 #include "lldb/DataFormatters/DataVisualization.h"
@@ -513,6 +515,9 @@
     if (sym_ctx.function && sym_ctx.function->IsTopLevelFunction())
       m_option_variable.show_globals = true;
 
+    bool is_po = m_varobj_options.use_objc;
+    auto language = frame->GuessLanguage();
+
     if (variable_list) {
       const Format format = m_option_format.GetFormat();
       options.SetFormat(format);
@@ -556,7 +561,10 @@
                                                     show_module))
                           s.PutCString(": ");
                       }
-                      valobj_sp->Dump(result.GetOutputStream(), options);
+
+                      CommandObjectDWIMPrint::MaybeAddPoHintAndDump(
+                          *valobj_sp.get(), options, language, is_po,
+                          result.GetOutputStream());
                     }
                   }
                 }
@@ -604,7 +612,8 @@
               Stream &output_stream = result.GetOutputStream();
               options.SetRootValueObjectName(
                   valobj_sp->GetParent() ? entry.c_str() : nullptr);
-              valobj_sp->Dump(output_stream, options);
+              CommandObjectDWIMPrint::MaybeAddPoHintAndDump(
+                  *valobj_sp.get(), options, language, is_po, output_stream);
             } else {
               if (auto error_cstr = error.AsCString(nullptr))
                 result.AppendError(error_cstr);
@@ -674,7 +683,9 @@
                     valobj_sp->GetPreferredDisplayLanguage());
                 options.SetRootValueObjectName(
                     var_sp ? var_sp->GetName().AsCString() : nullptr);
-                valobj_sp->Dump(result.GetOutputStream(), options);
+                CommandObjectDWIMPrint::MaybeAddPoHintAndDump(
+                    *valobj_sp.get(), options, language, is_po,
+                    result.GetOutputStream());
               }
             }
           }
@@ -694,8 +705,11 @@
             options.SetFormat(m_option_format.GetFormat());
             options.SetVariableFormatDisplayLanguage(
                 rec_value_sp->GetPreferredDisplayLanguage());
+            rec_value_sp->GetPreferredDisplayLanguage();
             options.SetRootValueObjectName(rec_value_sp->GetName().AsCString());
-            rec_value_sp->Dump(result.GetOutputStream(), options);
+            CommandObjectDWIMPrint::MaybeAddPoHintAndDump(
+                *rec_value_sp.get(), options, language, is_po,
+                result.GetOutputStream());
           }
         }
       }
Index: lldb/source/Commands/CommandObjectExpression.cpp
===================================================================
--- lldb/source/Commands/CommandObjectExpression.cpp
+++ lldb/source/Commands/CommandObjectExpression.cpp
@@ -9,6 +9,8 @@
 #include "llvm/ADT/StringRef.h"
 
 #include "CommandObjectExpression.h"
+
+#include "CommandObjectDWIMPrint.h"
 #include "lldb/Core/Debugger.h"
 #include "lldb/Expression/ExpressionVariable.h"
 #include "lldb/Expression/REPL.h"
@@ -473,7 +475,13 @@
         options.SetVariableFormatDisplayLanguage(
             result_valobj_sp->GetPreferredDisplayLanguage());
 
-        result_valobj_sp->Dump(output_stream, options);
+        bool is_po = m_varobj_options.use_objc;
+        lldb::LanguageType language = m_command_options.language;
+        if (language == lldb::eLanguageTypeUnknown && frame)
+          language = frame->GuessLanguage();
+        CommandObjectDWIMPrint::MaybeAddPoHintAndDump(*result_valobj_sp.get(),
+                                                      options, language, is_po,
+                                                      result.GetOutputStream());
 
         if (suppress_result)
           if (auto result_var_sp =
Index: lldb/source/Commands/CommandObjectDWIMPrint.h
===================================================================
--- lldb/source/Commands/CommandObjectDWIMPrint.h
+++ lldb/source/Commands/CommandObjectDWIMPrint.h
@@ -43,6 +43,13 @@
   HandleArgumentCompletion(CompletionRequest &request,
                            OptionElementVector &opt_element_vector) override;
 
+  /// Add a hint if object description was requested, but no description
+  /// function was implemented, and dump valobj to output_stream after.
+  static void MaybeAddPoHintAndDump(ValueObject &valobj,
+                                    const DumpValueObjectOptions &dump_options,
+                                    lldb::LanguageType language, bool is_po,
+                                    Stream &output_stream);
+
 private:
   bool DoExecute(llvm::StringRef command, CommandReturnObject &result) override;
 
Index: lldb/source/Commands/CommandObjectDWIMPrint.cpp
===================================================================
--- lldb/source/Commands/CommandObjectDWIMPrint.cpp
+++ lldb/source/Commands/CommandObjectDWIMPrint.cpp
@@ -25,6 +25,8 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/FormatVariadic.h"
 
+#include <regex>
+
 using namespace llvm;
 using namespace lldb;
 using namespace lldb_private;
@@ -56,6 +58,33 @@
       GetCommandInterpreter(), lldb::eVariablePathCompletion, request, nullptr);
 }
 
+void CommandObjectDWIMPrint::MaybeAddPoHintAndDump(
+    ValueObject &valobj, const DumpValueObjectOptions &dump_options,
+    lldb::LanguageType language, bool is_po, Stream &output_stream) {
+  // Identify the default output of object description for Swift and Objective-C
+  // "<Name: 0x...>. The regex is:
+  // - Start with "<".
+  // - Followed by 1 or more non-whitespace characters.
+  // - Followed by ": 0x".
+  // - Followed by 5 or more hex digits.
+  // - Followed by ">".
+  // - End with zero or more whitespace characters.
+  static const std::regex swift_class_regex("^<\\S+: 0x[[:xdigit:]]{5,}>\\s*$");
+
+  StreamString temp_result_stream;
+  valobj.Dump(temp_result_stream, dump_options);
+  const char *temp_result = temp_result_stream.GetData();
+  if ((language == lldb::eLanguageTypeSwift ||
+       language == lldb::eLanguageTypeObjC) &&
+      is_po && std::regex_match(temp_result, swift_class_regex))
+    output_stream
+        << "note: object description requested, but type doesn't implement "
+           "a custom object description. Consider using \"p\" instead of "
+           "\"po\"\n";
+
+  output_stream << temp_result;
+}
+
 bool CommandObjectDWIMPrint::DoExecute(StringRef command,
                                        CommandReturnObject &result) {
   m_option_group.NotifyOptionParsingStarting(&m_exe_ctx);
@@ -95,8 +124,15 @@
       m_expr_options.m_verbosity, m_format_options.GetFormat());
   dump_options.SetHideRootName(suppress_result);
 
+  bool is_po = m_varobj_options.use_objc;
+
   StackFrame *frame = m_exe_ctx.GetFramePtr();
 
+  // Either Swift was explicitly specified, or the frame is Swift.
+  lldb::LanguageType language = m_expr_options.language;
+  if (language == lldb::eLanguageTypeUnknown && frame)
+    language = frame->GuessLanguage();
+
   // First, try `expr` as the name of a frame variable.
   if (frame) {
     auto valobj_sp = frame->FindVariable(ConstString(expr));
@@ -114,7 +150,9 @@
                                         flags, expr);
       }
 
-      valobj_sp->Dump(result.GetOutputStream(), dump_options);
+      MaybeAddPoHintAndDump(*valobj_sp.get(), dump_options, language, is_po,
+                            result.GetOutputStream());
+
       result.SetStatus(eReturnStatusSuccessFinishResult);
       return true;
     }
@@ -136,7 +174,8 @@
       }
 
       if (valobj_sp->GetError().GetError() != UserExpression::kNoResult)
-        valobj_sp->Dump(result.GetOutputStream(), dump_options);
+        MaybeAddPoHintAndDump(*valobj_sp.get(), dump_options, language, is_po,
+                              result.GetOutputStream());
 
       if (suppress_result)
         if (auto result_var_sp =
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to