Files
clang-p2996/lldb/source/Target/ObjCObjectPrinter.cpp
Jim Ingham 53c47f1e2f 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.

llvm-svn: 113660
2010-09-10 23:12:17 +00:00

123 lines
3.6 KiB
C++

//===-- 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 "lldb/Target/ObjCObjectPrinter.h"
using namespace lldb;
using namespace lldb_private;
//----------------------------------------------------------------------
// ObjCObjectPrinter constructor
//----------------------------------------------------------------------
ObjCObjectPrinter::ObjCObjectPrinter (Process &process) :
m_process(process)
{
}
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
ObjCObjectPrinter::~ObjCObjectPrinter ()
{
}
bool
ObjCObjectPrinter::PrintObject (Stream &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.
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
Error error;
std::vector<char> desc;
while (1)
{
char byte = '\0';
if (exe_ctx.process->ReadMemory(result_ptr + desc.size(), &byte, 1, error) != 1)
break;
desc.push_back(byte);
if (byte == '\0')
break;
}
if (!desc.empty())
{
str.PutCString(&desc.front());
return true;
}
return false;
}
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();
}