summaryrefslogtreecommitdiff
path: root/lldb/source/DataFormatters/ValueObjectPrinter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/DataFormatters/ValueObjectPrinter.cpp')
-rw-r--r--lldb/source/DataFormatters/ValueObjectPrinter.cpp91
1 files changed, 55 insertions, 36 deletions
diff --git a/lldb/source/DataFormatters/ValueObjectPrinter.cpp b/lldb/source/DataFormatters/ValueObjectPrinter.cpp
index c2933d857458..ce24a7866e53 100644
--- a/lldb/source/DataFormatters/ValueObjectPrinter.cpp
+++ b/lldb/source/DataFormatters/ValueObjectPrinter.cpp
@@ -69,15 +69,13 @@ void ValueObjectPrinter::Init(
SetupMostSpecializedValue();
}
-bool ValueObjectPrinter::PrintValueObject() {
+llvm::Error ValueObjectPrinter::PrintValueObject() {
// If the incoming ValueObject is in an error state, the best we're going to
// get out of it is its type. But if we don't even have that, just print
// the error and exit early.
if (m_orig_valobj.GetError().Fail() &&
- !m_orig_valobj.GetCompilerType().IsValid()) {
- m_stream->Printf("Error: '%s'", m_orig_valobj.GetError().AsCString());
- return true;
- }
+ !m_orig_valobj.GetCompilerType().IsValid())
+ return m_orig_valobj.GetError().ToError();
if (ShouldPrintValueObject()) {
PrintLocationIfNeeded();
@@ -93,11 +91,10 @@ bool ValueObjectPrinter::PrintValueObject() {
PrintValueAndSummaryIfNeeded(value_printed, summary_printed);
if (m_val_summary_ok)
- PrintChildrenIfNeeded(value_printed, summary_printed);
- else
- m_stream->EOL();
+ return PrintChildrenIfNeeded(value_printed, summary_printed);
+ m_stream->EOL();
- return true;
+ return llvm::Error::success();
}
ValueObject &ValueObjectPrinter::GetMostSpecializedValue() {
@@ -147,13 +144,21 @@ void ValueObjectPrinter::SetupMostSpecializedValue() {
"SetupMostSpecialized value must compute a valid ValueObject");
}
-const char *ValueObjectPrinter::GetDescriptionForDisplay() {
+llvm::Expected<std::string> ValueObjectPrinter::GetDescriptionForDisplay() {
ValueObject &valobj = GetMostSpecializedValue();
- const char *str = valobj.GetObjectDescription();
+ llvm::Expected<std::string> maybe_str = valobj.GetObjectDescription();
+ if (maybe_str)
+ return maybe_str;
+
+ const char *str = nullptr;
if (!str)
str = valobj.GetSummaryAsCString();
if (!str)
str = valobj.GetValueAsCString();
+
+ if (!str)
+ return maybe_str;
+ llvm::consumeError(maybe_str.takeError());
return str;
}
@@ -463,34 +468,38 @@ bool ValueObjectPrinter::PrintValueAndSummaryIfNeeded(bool &value_printed,
return !error_printed;
}
-bool ValueObjectPrinter::PrintObjectDescriptionIfNeeded(bool value_printed,
- bool summary_printed) {
+llvm::Error
+ValueObjectPrinter::PrintObjectDescriptionIfNeeded(bool value_printed,
+ bool summary_printed) {
if (ShouldPrintValueObject()) {
// let's avoid the overly verbose no description error for a nil thing
if (m_options.m_use_objc && !IsNil() && !IsUninitialized() &&
(!m_options.m_pointer_as_array)) {
if (!m_options.m_hide_value || ShouldShowName())
- m_stream->Printf(" ");
- const char *object_desc = nullptr;
- if (value_printed || summary_printed)
- object_desc = GetMostSpecializedValue().GetObjectDescription();
- else
- object_desc = GetDescriptionForDisplay();
- if (object_desc && *object_desc) {
+ *m_stream << ' ';
+ llvm::Expected<std::string> object_desc =
+ (value_printed || summary_printed)
+ ? GetMostSpecializedValue().GetObjectDescription()
+ : GetDescriptionForDisplay();
+ if (!object_desc) {
+ // If no value or summary was printed, surface the error.
+ if (!value_printed && !summary_printed)
+ return object_desc.takeError();
+ // Otherwise gently nudge the user that they should have used
+ // `p` instead of `po`. Unfortunately we cannot be more direct
+ // about this, because we don't actually know what the user did.
+ *m_stream << "warning: no object description available\n";
+ llvm::consumeError(object_desc.takeError());
+ } else {
+ *m_stream << *object_desc;
// If the description already ends with a \n don't add another one.
- size_t object_end = strlen(object_desc) - 1;
- if (object_desc[object_end] == '\n')
- m_stream->Printf("%s", object_desc);
- else
- m_stream->Printf("%s\n", object_desc);
- return true;
- } else if (!value_printed && !summary_printed)
- return true;
- else
- return false;
+ if (object_desc->empty() || object_desc->back() != '\n')
+ *m_stream << '\n';
+ }
+ return llvm::Error::success();
}
}
- return true;
+ return llvm::Error::success();
}
bool DumpValueObjectOptions::PointerDepth::CanAllowExpansion() const {
@@ -619,7 +628,13 @@ void ValueObjectPrinter::PrintChild(
ValueObjectPrinter child_printer(*(child_sp.get()), m_stream, child_options,
ptr_depth, m_curr_depth + 1,
m_printed_instance_pointers);
- child_printer.PrintValueObject();
+ llvm::Error error = child_printer.PrintValueObject();
+ if (error) {
+ if (m_stream)
+ *m_stream << "error: " << toString(std::move(error));
+ else
+ llvm::consumeError(std::move(error));
+ }
}
}
@@ -808,9 +823,12 @@ bool ValueObjectPrinter::PrintChildrenOneLiner(bool hide_names) {
return true;
}
-void ValueObjectPrinter::PrintChildrenIfNeeded(bool value_printed,
- bool summary_printed) {
- PrintObjectDescriptionIfNeeded(value_printed, summary_printed);
+llvm::Error ValueObjectPrinter::PrintChildrenIfNeeded(bool value_printed,
+ bool summary_printed) {
+ auto error = PrintObjectDescriptionIfNeeded(value_printed, summary_printed);
+ if (error)
+ return error;
+
ValueObject &valobj = GetMostSpecializedValue();
DumpValueObjectOptions::PointerDepth curr_ptr_depth = m_ptr_depth;
@@ -826,7 +844,7 @@ void ValueObjectPrinter::PrintChildrenIfNeeded(bool value_printed,
if (m_printed_instance_pointers->count(instance_ptr_value)) {
// We already printed this instance-is-pointer thing, so don't expand it.
m_stream->PutCString(" {...}\n");
- return;
+ return llvm::Error::success();
} else {
// Remember this guy for future reference.
m_printed_instance_pointers->emplace(instance_ptr_value);
@@ -854,6 +872,7 @@ void ValueObjectPrinter::PrintChildrenIfNeeded(bool value_printed,
.SetReachedMaximumDepth();
} else
m_stream->EOL();
+ return llvm::Error::success();
}
bool ValueObjectPrinter::HasReachedMaximumDepth() {