aboutsummaryrefslogtreecommitdiff
path: root/lldb
diff options
context:
space:
mode:
authorAdrian Prantl <aprantl@apple.com>2024-06-17 17:07:36 -0700
committerAdrian Prantl <aprantl@apple.com>2024-06-20 10:32:06 -0700
commitf900644ae2b6c7a485673974688a62c3f3301dcc (patch)
tree6c336655fbaec0accde760dce9c060b548960de5 /lldb
parentd1bc75c0bce141b94f9afadfde4e784760735ec0 (diff)
downloadllvm-f900644ae2b6c7a485673974688a62c3f3301dcc.zip
llvm-f900644ae2b6c7a485673974688a62c3f3301dcc.tar.gz
llvm-f900644ae2b6c7a485673974688a62c3f3301dcc.tar.bz2
Refactor GetObjectDescription() to return llvm::Expected (NFC)
This is de facto an NFC change for Objective-C but will benefit the Swift language plugin.
Diffstat (limited to 'lldb')
-rw-r--r--lldb/include/lldb/Core/ValueObject.h2
-rw-r--r--lldb/include/lldb/DataFormatters/ValueObjectPrinter.h7
-rw-r--r--lldb/include/lldb/Target/LanguageRuntime.h9
-rw-r--r--lldb/source/API/SBValue.cpp5
-rw-r--r--lldb/source/Core/ValueObject.cpp44
-rw-r--r--lldb/source/DataFormatters/ValueObjectPrinter.cpp73
-rw-r--r--lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp13
-rw-r--r--lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h6
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp57
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h6
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/GNUstepObjCRuntime/GNUstepObjCRuntime.cpp18
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/GNUstepObjCRuntime/GNUstepObjCRuntime.h6
12 files changed, 143 insertions, 103 deletions
diff --git a/lldb/include/lldb/Core/ValueObject.h b/lldb/include/lldb/Core/ValueObject.h
index 205d9ad..93eb3e8 100644
--- a/lldb/include/lldb/Core/ValueObject.h
+++ b/lldb/include/lldb/Core/ValueObject.h
@@ -537,7 +537,7 @@ public:
std::string &destination,
const TypeSummaryOptions &options);
- const char *GetObjectDescription();
+ llvm::Expected<std::string> GetObjectDescription();
bool HasSpecialPrintableRepresentation(
ValueObjectRepresentationStyle val_obj_display,
diff --git a/lldb/include/lldb/DataFormatters/ValueObjectPrinter.h b/lldb/include/lldb/DataFormatters/ValueObjectPrinter.h
index 7460370..f9deb6e 100644
--- a/lldb/include/lldb/DataFormatters/ValueObjectPrinter.h
+++ b/lldb/include/lldb/DataFormatters/ValueObjectPrinter.h
@@ -75,7 +75,7 @@ protected:
void SetupMostSpecializedValue();
- const char *GetDescriptionForDisplay();
+ llvm::Expected<std::string> GetDescriptionForDisplay();
const char *GetRootNameForDisplay();
@@ -108,7 +108,8 @@ protected:
bool PrintValueAndSummaryIfNeeded(bool &value_printed, bool &summary_printed);
- bool PrintObjectDescriptionIfNeeded(bool value_printed, bool summary_printed);
+ llvm::Error PrintObjectDescriptionIfNeeded(bool value_printed,
+ bool summary_printed);
bool
ShouldPrintChildren(DumpValueObjectOptions::PointerDepth &curr_ptr_depth);
@@ -132,7 +133,7 @@ protected:
PrintChildren(bool value_printed, bool summary_printed,
const DumpValueObjectOptions::PointerDepth &curr_ptr_depth);
- void PrintChildrenIfNeeded(bool value_printed, bool summary_printed);
+ llvm::Error PrintChildrenIfNeeded(bool value_printed, bool summary_printed);
bool PrintChildrenOneLiner(bool hide_names);
diff --git a/lldb/include/lldb/Target/LanguageRuntime.h b/lldb/include/lldb/Target/LanguageRuntime.h
index a2a9c016..d093dcc 100644
--- a/lldb/include/lldb/Target/LanguageRuntime.h
+++ b/lldb/include/lldb/Target/LanguageRuntime.h
@@ -73,11 +73,12 @@ public:
return nullptr;
}
- virtual bool GetObjectDescription(Stream &str, ValueObject &object) = 0;
-
- virtual bool GetObjectDescription(Stream &str, Value &value,
- ExecutionContextScope *exe_scope) = 0;
+ virtual llvm::Error GetObjectDescription(Stream &str,
+ ValueObject &object) = 0;
+ virtual llvm::Error
+ GetObjectDescription(Stream &str, Value &value,
+ ExecutionContextScope *exe_scope) = 0;
struct VTableInfo {
Address addr; /// Address of the vtable's virtual function table
diff --git a/lldb/source/API/SBValue.cpp b/lldb/source/API/SBValue.cpp
index 1b9cae6..10a691c 100644
--- a/lldb/source/API/SBValue.cpp
+++ b/lldb/source/API/SBValue.cpp
@@ -379,7 +379,10 @@ const char *SBValue::GetObjectDescription() {
if (!value_sp)
return nullptr;
- return ConstString(value_sp->GetObjectDescription()).GetCString();
+ llvm::Expected<std::string> str = value_sp->GetObjectDescription();
+ if (!str)
+ return ConstString("error: " + toString(str.takeError())).AsCString();
+ return ConstString(*str).AsCString();
}
SBType SBValue::GetType() {
diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp
index cf0f557..8f72efc 100644
--- a/lldb/source/Core/ValueObject.cpp
+++ b/lldb/source/Core/ValueObject.cpp
@@ -989,41 +989,46 @@ ValueObject::ReadPointedString(lldb::WritableDataBufferSP &buffer_sp,
return {total_bytes_read, was_capped};
}
-const char *ValueObject::GetObjectDescription() {
+llvm::Expected<std::string> ValueObject::GetObjectDescription() {
if (!UpdateValueIfNeeded(true))
- return nullptr;
+ return llvm::createStringError("could not update value");
// Return cached value.
if (!m_object_desc_str.empty())
- return m_object_desc_str.c_str();
+ return m_object_desc_str;
ExecutionContext exe_ctx(GetExecutionContextRef());
Process *process = exe_ctx.GetProcessPtr();
if (!process)
- return nullptr;
+ return llvm::createStringError("no process");
// Returns the object description produced by one language runtime.
- auto get_object_description = [&](LanguageType language) -> const char * {
+ auto get_object_description =
+ [&](LanguageType language) -> llvm::Expected<std::string> {
if (LanguageRuntime *runtime = process->GetLanguageRuntime(language)) {
StreamString s;
- if (runtime->GetObjectDescription(s, *this)) {
- m_object_desc_str.append(std::string(s.GetString()));
- return m_object_desc_str.c_str();
- }
+ if (llvm::Error error = runtime->GetObjectDescription(s, *this))
+ return error;
+ m_object_desc_str = s.GetString();
+ return m_object_desc_str;
}
- return nullptr;
+ return llvm::createStringError("no native language runtime");
};
// Try the native language runtime first.
LanguageType native_language = GetObjectRuntimeLanguage();
- if (const char *desc = get_object_description(native_language))
+ llvm::Expected<std::string> desc = get_object_description(native_language);
+ if (desc)
return desc;
// Try the Objective-C language runtime. This fallback is necessary
// for Objective-C++ and mixed Objective-C / C++ programs.
- if (Language::LanguageIsCFamily(native_language))
+ if (Language::LanguageIsCFamily(native_language)) {
+ // We're going to try again, so let's drop the first error.
+ llvm::consumeError(desc.takeError());
return get_object_description(eLanguageTypeObjC);
- return nullptr;
+ }
+ return desc;
}
bool ValueObject::GetValueAsCString(const lldb_private::TypeFormatImpl &format,
@@ -1472,9 +1477,16 @@ bool ValueObject::DumpPrintableRepresentation(
str = GetSummaryAsCString();
break;
- case eValueObjectRepresentationStyleLanguageSpecific:
- str = GetObjectDescription();
- break;
+ case eValueObjectRepresentationStyleLanguageSpecific: {
+ llvm::Expected<std::string> desc = GetObjectDescription();
+ if (!desc) {
+ strm << "error: " << toString(desc.takeError());
+ str = strm.GetString();
+ } else {
+ strm << *desc;
+ str = strm.GetString();
+ }
+ } break;
case eValueObjectRepresentationStyleLocation:
str = GetLocationAsCString();
diff --git a/lldb/source/DataFormatters/ValueObjectPrinter.cpp b/lldb/source/DataFormatters/ValueObjectPrinter.cpp
index a81a5172..ce24a78 100644
--- a/lldb/source/DataFormatters/ValueObjectPrinter.cpp
+++ b/lldb/source/DataFormatters/ValueObjectPrinter.cpp
@@ -91,9 +91,8 @@ llvm::Error 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 llvm::Error::success();
}
@@ -145,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;
}
@@ -461,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 {
@@ -812,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;
@@ -830,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);
@@ -858,6 +872,7 @@ void ValueObjectPrinter::PrintChildrenIfNeeded(bool value_printed,
.SetReachedMaximumDepth();
} else
m_stream->EOL();
+ return llvm::Error::success();
}
bool ValueObjectPrinter::HasReachedMaximumDepth() {
diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp
index 300ecc8..c7202a4 100644
--- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp
@@ -47,16 +47,17 @@ bool CPPLanguageRuntime::IsAllowedRuntimeValue(ConstString name) {
return name == g_this || name == g_promise || name == g_coro_frame;
}
-bool CPPLanguageRuntime::GetObjectDescription(Stream &str,
- ValueObject &object) {
+llvm::Error CPPLanguageRuntime::GetObjectDescription(Stream &str,
+ ValueObject &object) {
// C++ has no generic way to do this.
- return false;
+ return llvm::createStringError("C++ does not support object descriptions");
}
-bool CPPLanguageRuntime::GetObjectDescription(
- Stream &str, Value &value, ExecutionContextScope *exe_scope) {
+llvm::Error
+CPPLanguageRuntime::GetObjectDescription(Stream &str, Value &value,
+ ExecutionContextScope *exe_scope) {
// C++ has no generic way to do this.
- return false;
+ return llvm::createStringError("C++ does not support object descriptions");
}
bool contains_lambda_identifier(llvm::StringRef &str_ref) {
diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h
index 1be58b7..57cfe282 100644
--- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h
+++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h
@@ -59,10 +59,10 @@ public:
process.GetLanguageRuntime(lldb::eLanguageTypeC_plus_plus));
}
- bool GetObjectDescription(Stream &str, ValueObject &object) override;
+ llvm::Error GetObjectDescription(Stream &str, ValueObject &object) override;
- bool GetObjectDescription(Stream &str, Value &value,
- ExecutionContextScope *exe_scope) override;
+ llvm::Error GetObjectDescription(Stream &str, Value &value,
+ ExecutionContextScope *exe_scope) override;
/// Obtain a ThreadPlan to get us into C++ constructs such as std::function.
///
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
index 9434376..800eda9 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
@@ -67,20 +67,21 @@ void AppleObjCRuntime::Terminate() {
AppleObjCRuntimeV1::Terminate();
}
-bool AppleObjCRuntime::GetObjectDescription(Stream &str, ValueObject &valobj) {
+llvm::Error AppleObjCRuntime::GetObjectDescription(Stream &str,
+ ValueObject &valobj) {
CompilerType compiler_type(valobj.GetCompilerType());
bool is_signed;
// ObjC objects can only be pointers (or numbers that actually represents
// pointers but haven't been typecast, because reasons..)
if (!compiler_type.IsIntegerType(is_signed) && !compiler_type.IsPointerType())
- return false;
+ return llvm::createStringError("not a pointer type");
// Make the argument list: we pass one arg, the address of our pointer, to
// the print function.
Value val;
if (!valobj.ResolveValue(val.GetScalar()))
- return false;
+ return llvm::createStringError("pointer value could not be resolved");
// Value Objects may not have a process in their ExecutionContextRef. But we
// need to have one in the ref we pass down to eventually call description.
@@ -91,20 +92,22 @@ bool AppleObjCRuntime::GetObjectDescription(Stream &str, ValueObject &valobj) {
} else {
exe_ctx.SetContext(valobj.GetTargetSP(), true);
if (!exe_ctx.HasProcessScope())
- return false;
+ return llvm::createStringError("no process");
}
return GetObjectDescription(str, val, exe_ctx.GetBestExecutionContextScope());
}
-bool AppleObjCRuntime::GetObjectDescription(Stream &strm, Value &value,
- ExecutionContextScope *exe_scope) {
+
+llvm::Error
+AppleObjCRuntime::GetObjectDescription(Stream &strm, Value &value,
+ ExecutionContextScope *exe_scope) {
if (!m_read_objc_library)
- return false;
+ return llvm::createStringError("Objective-C runtime not loaded");
ExecutionContext exe_ctx;
exe_scope->CalculateExecutionContext(exe_ctx);
Process *process = exe_ctx.GetProcessPtr();
if (!process)
- return false;
+ return llvm::createStringError("no process");
// We need other parts of the exe_ctx, but the processes have to match.
assert(m_process == process);
@@ -112,25 +115,25 @@ bool AppleObjCRuntime::GetObjectDescription(Stream &strm, Value &value,
// Get the function address for the print function.
const Address *function_address = GetPrintForDebuggerAddr();
if (!function_address)
- return false;
+ return llvm::createStringError("no print function");
Target *target = exe_ctx.GetTargetPtr();
CompilerType compiler_type = value.GetCompilerType();
if (compiler_type) {
- if (!TypeSystemClang::IsObjCObjectPointerType(compiler_type)) {
- strm.Printf("Value doesn't point to an ObjC object.\n");
- return false;
- }
+ if (!TypeSystemClang::IsObjCObjectPointerType(compiler_type))
+ return llvm::createStringError(
+ "Value doesn't point to an ObjC object.\n");
} else {
// If it is not a pointer, see if we can make it into a pointer.
TypeSystemClangSP scratch_ts_sp =
ScratchTypeSystemClang::GetForTarget(*target);
if (!scratch_ts_sp)
- return false;
+ return llvm::createStringError("no scratch type system");
CompilerType opaque_type = scratch_ts_sp->GetBasicType(eBasicTypeObjCID);
if (!opaque_type)
- opaque_type = scratch_ts_sp->GetBasicType(eBasicTypeVoid).GetPointerType();
+ opaque_type =
+ scratch_ts_sp->GetBasicType(eBasicTypeVoid).GetPointerType();
// value.SetContext(Value::eContextTypeClangType, opaque_type_ptr);
value.SetCompilerType(opaque_type);
}
@@ -142,14 +145,14 @@ bool AppleObjCRuntime::GetObjectDescription(Stream &strm, Value &value,
TypeSystemClangSP scratch_ts_sp =
ScratchTypeSystemClang::GetForTarget(*target);
if (!scratch_ts_sp)
- return false;
+ return llvm::createStringError("no scratch type system");
CompilerType return_compiler_type = scratch_ts_sp->GetCStringType(true);
Value ret;
// ret.SetContext(Value::eContextTypeClangType, return_compiler_type);
ret.SetCompilerType(return_compiler_type);
- if (exe_ctx.GetFramePtr() == nullptr) {
+ if (!exe_ctx.GetFramePtr()) {
Thread *thread = exe_ctx.GetThreadPtr();
if (thread == nullptr) {
exe_ctx.SetThreadSP(process->GetThreadList().GetSelectedThread());
@@ -173,10 +176,11 @@ bool AppleObjCRuntime::GetObjectDescription(Stream &strm, Value &value,
arg_value_list, "objc-object-description", error));
if (error.Fail()) {
m_print_object_caller_up.reset();
- strm.Printf("Could not get function runner to call print for debugger "
- "function: %s.",
- error.AsCString());
- return false;
+ return llvm::createStringError(
+ llvm::Twine(
+ "could not get function runner to call print for debugger "
+ "function: ") +
+ error.AsCString());
}
m_print_object_caller_up->InsertFunction(exe_ctx, wrapper_struct_addr,
diagnostics);
@@ -195,10 +199,9 @@ bool AppleObjCRuntime::GetObjectDescription(Stream &strm, Value &value,
ExpressionResults results = m_print_object_caller_up->ExecuteFunction(
exe_ctx, &wrapper_struct_addr, options, diagnostics, ret);
- if (results != eExpressionCompleted) {
- strm.Printf("Error evaluating Print Object function: %d.\n", results);
- return false;
- }
+ if (results != eExpressionCompleted)
+ return llvm::createStringError(
+ "Error evaluating Print Object function: %d.\n", results);
addr_t result_ptr = ret.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
@@ -213,7 +216,9 @@ bool AppleObjCRuntime::GetObjectDescription(Stream &strm, Value &value,
strm.Write(buf, curr_len);
cstr_len += curr_len;
}
- return cstr_len > 0;
+ if (cstr_len > 0)
+ return llvm::Error::success();
+ return llvm::createStringError("empty object description");
}
lldb::ModuleSP AppleObjCRuntime::GetObjCModule() {
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h
index cfeec3d6..da58d44 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h
@@ -44,10 +44,10 @@ public:
}
// These are generic runtime functions:
- bool GetObjectDescription(Stream &str, Value &value,
- ExecutionContextScope *exe_scope) override;
+ llvm::Error GetObjectDescription(Stream &str, Value &value,
+ ExecutionContextScope *exe_scope) override;
- bool GetObjectDescription(Stream &str, ValueObject &object) override;
+ llvm::Error GetObjectDescription(Stream &str, ValueObject &object) override;
bool CouldHaveDynamicValue(ValueObject &in_value) override;
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/GNUstepObjCRuntime/GNUstepObjCRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/GNUstepObjCRuntime/GNUstepObjCRuntime.cpp
index 39b3e81..58b8387 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/GNUstepObjCRuntime/GNUstepObjCRuntime.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/GNUstepObjCRuntime/GNUstepObjCRuntime.cpp
@@ -104,15 +104,17 @@ GNUstepObjCRuntime::GNUstepObjCRuntime(Process *process)
ReadObjCLibraryIfNeeded(process->GetTarget().GetImages());
}
-bool GNUstepObjCRuntime::GetObjectDescription(Stream &str,
- ValueObject &valobj) {
- // TODO: ObjC has a generic way to do this
- return false;
+llvm::Error GNUstepObjCRuntime::GetObjectDescription(Stream &str,
+ ValueObject &valobj) {
+ return llvm::createStringError(
+ "LLDB's GNUStep runtime does not support object description");
}
-bool GNUstepObjCRuntime::GetObjectDescription(
- Stream &strm, Value &value, ExecutionContextScope *exe_scope) {
- // TODO: ObjC has a generic way to do this
- return false;
+
+llvm::Error
+GNUstepObjCRuntime::GetObjectDescription(Stream &strm, Value &value,
+ ExecutionContextScope *exe_scope) {
+ return llvm::createStringError(
+ "LLDB's GNUStep runtime does not support object description");
}
bool GNUstepObjCRuntime::CouldHaveDynamicValue(ValueObject &in_value) {
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/GNUstepObjCRuntime/GNUstepObjCRuntime.h b/lldb/source/Plugins/LanguageRuntime/ObjC/GNUstepObjCRuntime/GNUstepObjCRuntime.h
index b220888..de24466 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/GNUstepObjCRuntime/GNUstepObjCRuntime.h
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/GNUstepObjCRuntime/GNUstepObjCRuntime.h
@@ -57,10 +57,10 @@ public:
//
// LanguageRuntime implementation
//
- bool GetObjectDescription(Stream &str, Value &value,
- ExecutionContextScope *exe_scope) override;
+ llvm::Error GetObjectDescription(Stream &str, Value &value,
+ ExecutionContextScope *exe_scope) override;
- bool GetObjectDescription(Stream &str, ValueObject &object) override;
+ llvm::Error GetObjectDescription(Stream &str, ValueObject &object) override;
bool CouldHaveDynamicValue(ValueObject &in_value) override;