Move the "Object Description" into the ValueObject, and the add an API to
SBValue to access it.  For now this is just the result of ObjC NSPrintForDebugger,
but could be extended.  Also store the results of the ObjC Object Printer in a
Stream, not a ConstString.


git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@113660 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/API/SBValue.cpp b/source/API/SBValue.cpp
index f92be9f..a90c1bf 100644
--- a/source/API/SBValue.cpp
+++ b/source/API/SBValue.cpp
@@ -176,6 +176,15 @@
     return value_string;
 }
 
+const char *
+SBValue::GetObjectDescription (const SBFrame &frame)
+{
+    const char *value_string = NULL;
+    if ( m_opaque_sp)
+        value_string = m_opaque_sp->GetObjectDescription (frame.get());
+    return value_string;
+}
+
 bool
 SBValue::GetValueDidChange (const SBFrame &frame)
 {
diff --git a/source/Commands/CommandObjectFrame.cpp b/source/Commands/CommandObjectFrame.cpp
index 013e8c9..d85a53e 100644
--- a/source/Commands/CommandObjectFrame.cpp
+++ b/source/Commands/CommandObjectFrame.cpp
@@ -444,41 +444,11 @@
                 
                 if (use_objc)
                 {
-                    if (!ClangASTContext::IsPointerType (valobj->GetOpaqueClangQualType()))
-                        return;
-                    
-                    if (!valobj->GetValueIsValid())
-                        return;
-                    
-                    Process *process = exe_scope->CalculateProcess();
-                    
-                    if (!process)
-                        return;
-                    
-                    Scalar scalar;
-                    
-                    if (!ClangASTType::GetValueAsScalar (valobj->GetClangAST(),
-                                                        valobj->GetOpaqueClangQualType(),
-                                                        valobj->GetDataExtractor(),
-                                                        0,
-                                                        valobj->GetByteSize(),
-                                                        scalar))
-                        return;
-                                        
-                    ConstString po_output;
-                    
-                    ExecutionContext exe_ctx;
-                    exe_scope->Calculate(exe_ctx);
-                    
-                    Value val(scalar);
-                    val.SetContext(Value::eContextTypeOpaqueClangQualType, 
-                                   ClangASTContext::GetVoidPtrType(valobj->GetClangAST(), false));
-                    
-                    if (!process->GetObjCObjectPrinter().PrintObject(po_output, val, exe_ctx))
-                        return;
-                    
-                    s.Printf("\n%s\n", po_output.GetCString());
-                                        
+                    const char *object_desc = valobj->GetObjectDescription(exe_scope);
+                    if (object_desc)
+                        s.Printf("\n%s\n", object_desc);
+                    else
+                        s.Printf ("No description available.\n");
                     return;
                 }
 
diff --git a/source/Core/ValueObject.cpp b/source/Core/ValueObject.cpp
index e14875b..c822e32 100644
--- a/source/Core/ValueObject.cpp
+++ b/source/Core/ValueObject.cpp
@@ -24,6 +24,7 @@
 #include "lldb/Symbol/ClangASTContext.h"
 #include "lldb/Symbol/Type.h"
 
+#include "lldb/Target/ExecutionContext.h"
 #include "lldb/Target/Process.h"
 #include "lldb/Target/RegisterContext.h"
 #include "lldb/Target/Thread.h"
@@ -48,6 +49,7 @@
     m_old_value_str (),
     m_location_str (),
     m_summary_str (),
+    m_object_desc_str (),
     m_children (),
     m_synthetic_children (),
     m_value_is_valid (false),
@@ -96,6 +98,7 @@
                 }
                 m_location_str.clear();
                 m_summary_str.clear();
+                m_object_desc_str.clear();
 
                 const bool value_was_valid = GetValueIsValid();
                 SetValueDidChange (false);
@@ -499,6 +502,48 @@
     return m_summary_str.c_str();
 }
 
+const char *
+ValueObject::GetObjectDescription (ExecutionContextScope *exe_scope)
+{
+    if (!m_object_desc_str.empty())
+        return m_object_desc_str.c_str();
+        
+    if (!ClangASTContext::IsPointerType (GetOpaqueClangQualType()))
+        return NULL;
+    
+    if (!GetValueIsValid())
+        return NULL;
+    
+    Process *process = exe_scope->CalculateProcess();
+    
+    if (!process)
+        return NULL;
+    
+    Scalar scalar;
+    
+    if (!ClangASTType::GetValueAsScalar (GetClangAST(),
+                                        GetOpaqueClangQualType(),
+                                        GetDataExtractor(),
+                                        0,
+                                        GetByteSize(),
+                                        scalar))
+        return NULL;
+                        
+    ExecutionContext exe_ctx;
+    exe_scope->Calculate(exe_ctx);
+    
+    Value val(scalar);
+    val.SetContext(Value::eContextTypeOpaqueClangQualType, 
+                   ClangASTContext::GetVoidPtrType(GetClangAST(), false));
+                   
+    StreamString s;
+    // FIXME: Check the runtime this object belongs to and get the appropriate object printer for the object kind.
+    if (process->GetObjCObjectPrinter().PrintObject(s, val, exe_ctx))
+    {
+        m_object_desc_str.append (s.GetData());
+    }
+    return m_object_desc_str.c_str();
+}
 
 const char *
 ValueObject::GetValueAsCString (ExecutionContextScope *exe_scope)
diff --git a/source/Target/ObjCObjectPrinter.cpp b/source/Target/ObjCObjectPrinter.cpp
index 1e436d7..72015e2 100644
--- a/source/Target/ObjCObjectPrinter.cpp
+++ b/source/Target/ObjCObjectPrinter.cpp
@@ -38,7 +38,7 @@
 }
 
 bool
-ObjCObjectPrinter::PrintObject (ConstString &str, Value &object_ptr, ExecutionContext &exe_ctx)
+ObjCObjectPrinter::PrintObject (Stream &str, Value &object_ptr, ExecutionContext &exe_ctx)
 {
     if (!exe_ctx.process)
         return false;
@@ -64,8 +64,14 @@
     lldb::addr_t wrapper_struct_addr = LLDB_INVALID_ADDRESS;
     func.InsertFunction(exe_ctx, wrapper_struct_addr, error_stream);
     // FIXME: Check result of ExecuteFunction.
-    func.ExecuteFunction(exe_ctx, &wrapper_struct_addr, error_stream, true, 1000, true, ret);
-        
+    ClangFunction::ExecutionResults results 
+        = func.ExecuteFunction(exe_ctx, &wrapper_struct_addr, error_stream, true, 1000, true, ret);
+    if (results != ClangFunction::eExecutionCompleted)
+    {
+        str.Printf("Error evaluating Print Object function: %d.\n", results);
+        return false;
+    }
+       
     addr_t result_ptr = ret.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
     
     // poor man's strcpy
@@ -86,7 +92,7 @@
     
     if (!desc.empty())
     {
-        str.SetCString(&desc.front());
+        str.PutCString(&desc.front());
         return true;
     }
     return false;