Initial checkin of lldb code from internal Apple repo.
git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@105619 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Target/ObjCObjectPrinter.cpp b/source/Target/ObjCObjectPrinter.cpp
new file mode 100644
index 0000000..81c73aa
--- /dev/null
+++ b/source/Target/ObjCObjectPrinter.cpp
@@ -0,0 +1,120 @@
+//===-- ObjCObjectPrinter.cpp -------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/StreamString.h"
+#include "lldb/Expression/ClangFunction.h"
+#include "lldb/Target/ExecutionContext.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Target.h"
+
+#include "ObjCObjectPrinter.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+//----------------------------------------------------------------------
+// ObjCObjectPrinter constructor
+//----------------------------------------------------------------------
+ObjCObjectPrinter::ObjCObjectPrinter (Process &process) :
+ m_process(process)
+{
+}
+
+//----------------------------------------------------------------------
+// Destructor
+//----------------------------------------------------------------------
+ObjCObjectPrinter::~ObjCObjectPrinter ()
+{
+}
+
+bool
+ObjCObjectPrinter::PrintObject (ConstString &str, Value &object_ptr, ExecutionContext &exe_ctx)
+{
+ if (!exe_ctx.process)
+ return false;
+
+ const Address *function_address = GetPrintForDebuggerAddr();
+
+ if (!function_address)
+ return false;
+
+ const char *target_triple = exe_ctx.process->GetTargetTriple().GetCString();
+ ClangASTContext *ast_context = exe_ctx.target->GetScratchClangASTContext();
+
+ void *return_qualtype = ast_context->GetCStringType(true);
+ Value ret;
+ ret.SetContext(Value::eContextTypeOpaqueClangQualType, return_qualtype);
+
+ ValueList arg_value_list;
+ arg_value_list.PushValue(object_ptr);
+
+ ClangFunction func(target_triple, ast_context, return_qualtype, *function_address, arg_value_list);
+ StreamString error_stream;
+
+ 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);
+
+ addr_t result_ptr = ret.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
+
+ // poor man's strcpy
+
+ size_t len = 0;
+ bool keep_reading = true;
+ Error error;
+ while (keep_reading)
+ {
+ char byte;
+
+ if (exe_ctx.process->ReadMemory(result_ptr + len, &byte, 1, error) != 1)
+ return false;
+
+ if (byte == '\0')
+ keep_reading = false;
+ else
+ ++len;
+ }
+
+ char desc[len + 1];
+
+ if (exe_ctx.process->ReadMemory(result_ptr, &desc[0], len + 1, error) != len + 1)
+ return false;
+
+ str.SetCString(desc);
+
+ return true;
+}
+
+Address *
+ObjCObjectPrinter::GetPrintForDebuggerAddr()
+{
+ if (!m_PrintForDebugger_addr.get())
+ {
+ ModuleList &modules = m_process.GetTarget().GetImages();
+
+ SymbolContextList contexts;
+ SymbolContext context;
+
+ if((!modules.FindSymbolsWithNameAndType(ConstString ("_NSPrintForDebugger"), eSymbolTypeCode, contexts)) &&
+ (!modules.FindSymbolsWithNameAndType(ConstString ("_CFPrintForDebugger"), eSymbolTypeCode, contexts)))
+ return NULL;
+
+ contexts.GetContextAtIndex(0, context);
+
+ m_PrintForDebugger_addr.reset(new Address(context.symbol->GetValue()));
+ }
+
+ return m_PrintForDebugger_addr.get();
+}
+