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
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits