blob: 81c73aa95815dcc8fe7600caebdb39099fed9bff [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- ObjCObjectPrinter.cpp -------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10// C Includes
11// C++ Includes
12// Other libraries and framework includes
13// Project includes
14#include "lldb/Core/StreamString.h"
15#include "lldb/Expression/ClangFunction.h"
16#include "lldb/Target/ExecutionContext.h"
17#include "lldb/Target/Process.h"
18#include "lldb/Target/Target.h"
19
20#include "ObjCObjectPrinter.h"
21
22using namespace lldb;
23using namespace lldb_private;
24
25//----------------------------------------------------------------------
26// ObjCObjectPrinter constructor
27//----------------------------------------------------------------------
28ObjCObjectPrinter::ObjCObjectPrinter (Process &process) :
29 m_process(process)
30{
31}
32
33//----------------------------------------------------------------------
34// Destructor
35//----------------------------------------------------------------------
36ObjCObjectPrinter::~ObjCObjectPrinter ()
37{
38}
39
40bool
41ObjCObjectPrinter::PrintObject (ConstString &str, Value &object_ptr, ExecutionContext &exe_ctx)
42{
43 if (!exe_ctx.process)
44 return false;
45
46 const Address *function_address = GetPrintForDebuggerAddr();
47
48 if (!function_address)
49 return false;
50
51 const char *target_triple = exe_ctx.process->GetTargetTriple().GetCString();
52 ClangASTContext *ast_context = exe_ctx.target->GetScratchClangASTContext();
53
54 void *return_qualtype = ast_context->GetCStringType(true);
55 Value ret;
56 ret.SetContext(Value::eContextTypeOpaqueClangQualType, return_qualtype);
57
58 ValueList arg_value_list;
59 arg_value_list.PushValue(object_ptr);
60
61 ClangFunction func(target_triple, ast_context, return_qualtype, *function_address, arg_value_list);
62 StreamString error_stream;
63
64 lldb::addr_t wrapper_struct_addr = LLDB_INVALID_ADDRESS;
65 func.InsertFunction(exe_ctx, wrapper_struct_addr, error_stream);
66 // FIXME: Check result of ExecuteFunction.
67 func.ExecuteFunction(exe_ctx, &wrapper_struct_addr, error_stream, true, 1000, true, ret);
68
69 addr_t result_ptr = ret.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
70
71 // poor man's strcpy
72
73 size_t len = 0;
74 bool keep_reading = true;
75 Error error;
76 while (keep_reading)
77 {
78 char byte;
79
80 if (exe_ctx.process->ReadMemory(result_ptr + len, &byte, 1, error) != 1)
81 return false;
82
83 if (byte == '\0')
84 keep_reading = false;
85 else
86 ++len;
87 }
88
89 char desc[len + 1];
90
91 if (exe_ctx.process->ReadMemory(result_ptr, &desc[0], len + 1, error) != len + 1)
92 return false;
93
94 str.SetCString(desc);
95
96 return true;
97}
98
99Address *
100ObjCObjectPrinter::GetPrintForDebuggerAddr()
101{
102 if (!m_PrintForDebugger_addr.get())
103 {
104 ModuleList &modules = m_process.GetTarget().GetImages();
105
106 SymbolContextList contexts;
107 SymbolContext context;
108
109 if((!modules.FindSymbolsWithNameAndType(ConstString ("_NSPrintForDebugger"), eSymbolTypeCode, contexts)) &&
110 (!modules.FindSymbolsWithNameAndType(ConstString ("_CFPrintForDebugger"), eSymbolTypeCode, contexts)))
111 return NULL;
112
113 contexts.GetContextAtIndex(0, context);
114
115 m_PrintForDebugger_addr.reset(new Address(context.symbol->GetValue()));
116 }
117
118 return m_PrintForDebugger_addr.get();
119}
120