diff options
author | Sean Callanan <scallanan@apple.com> | 2010-12-13 22:46:15 +0000 |
---|---|---|
committer | Sean Callanan <scallanan@apple.com> | 2010-12-13 22:46:15 +0000 |
commit | 1782783095b51000831c7d2fd1d763355b5adc0f (patch) | |
tree | fc296a108c96feda93188471be524ad16ed3e04c /lldb/source/Expression/ClangUserExpression.cpp | |
parent | 4efa445f3cd10e828a6022ca2ea53ca827dde6a7 (diff) | |
download | bcm5719-llvm-1782783095b51000831c7d2fd1d763355b5adc0f.tar.gz bcm5719-llvm-1782783095b51000831c7d2fd1d763355b5adc0f.zip |
Added support for generating expressions that have
access to the members of the Objective-C self object.
The approach we take is to generate the method as a
@category on top of the self object, and to pass the
"self" pointer to it. (_cmd is currently NULL.)
Most changes are in ClangExpressionDeclMap, but the
change that adds support to the ABIs to pass _cmd
touches a fair amount of code.
llvm-svn: 121722
Diffstat (limited to 'lldb/source/Expression/ClangUserExpression.cpp')
-rw-r--r-- | lldb/source/Expression/ClangUserExpression.cpp | 72 |
1 files changed, 60 insertions, 12 deletions
diff --git a/lldb/source/Expression/ClangUserExpression.cpp b/lldb/source/Expression/ClangUserExpression.cpp index 366b10e6dce..86696661019 100644 --- a/lldb/source/Expression/ClangUserExpression.cpp +++ b/lldb/source/Expression/ClangUserExpression.cpp @@ -174,6 +174,27 @@ ClangUserExpression::Parse (Stream &error_stream, m_needs_object_ptr = true; } + else if(m_objectivec) + { + const char *function_name = FunctionName(); + + m_transformed_stream.Printf("%s \n" + "@interface $__lldb_objc_class ($__lldb_category) \n" + "-(void)%s:(void *)$__lldb_arg; \n" + "@end \n" + "@implementation $__lldb_objc_class ($__lldb_category) \n" + "-(void)%s:(void *)$__lldb_arg \n" + "{ \n" + " %s; \n" + "} \n" + "@end \n", + m_expr_prefix.c_str(), + function_name, + function_name, + m_expr_text.c_str()); + + m_needs_object_ptr = true; + } else { m_transformed_stream.Printf("%s \n" @@ -297,14 +318,31 @@ ClangUserExpression::PrepareToExecuteJITExpression (Stream &error_stream, if (m_jit_addr != LLDB_INVALID_ADDRESS) { - Error materialize_error; - - if (m_needs_object_ptr && !(m_expr_decl_map->GetObjectPointer(object_ptr, exe_ctx, materialize_error))) + if (m_needs_object_ptr) { - error_stream.Printf("Couldn't get required object pointer: %s\n", materialize_error.AsCString()); - return false; + ConstString object_name; + + if (m_cplusplus) + { + object_name.SetCString("this"); + } + else if (m_objectivec) + { + object_name.SetCString("self"); + } + else + { + error_stream.Printf("Need object pointer but don't know the language\n"); + return false; + } + + if (!(m_expr_decl_map->GetObjectPointer(object_ptr, object_name, exe_ctx, materialize_error))) + { + error_stream.Printf("Couldn't get required object pointer: %s\n", materialize_error.AsCString()); + return false; + } } if (!m_expr_decl_map->Materialize(exe_ctx, struct_address, materialize_error)) @@ -351,19 +389,22 @@ ClangUserExpression::GetThreadPlanToExecuteJITExpression (Stream &error_stream, lldb::addr_t struct_address; lldb::addr_t object_ptr = NULL; + lldb::addr_t cmd_ptr = NULL; PrepareToExecuteJITExpression (error_stream, exe_ctx, struct_address, object_ptr); // FIXME: This should really return a ThreadPlanCallUserExpression, in order to make sure that we don't release the // ClangUserExpression resources before the thread plan finishes execution in the target. But because we are - // forcing unwind_on_error to be true here, in practical terms that can't happen. + // forcing unwind_on_error to be true here, in practical terms that can't happen. + return ClangFunction::GetThreadPlanToCallFunction (exe_ctx, m_jit_addr, struct_address, error_stream, true, true, - (m_needs_object_ptr ? &object_ptr : NULL)); + (m_needs_object_ptr ? &object_ptr : NULL), + (m_needs_object_ptr && m_objectivec) ? &cmd_ptr : NULL); } bool @@ -423,17 +464,24 @@ ClangUserExpression::Execute (Stream &error_stream, lldb::addr_t struct_address; lldb::addr_t object_ptr = NULL; + lldb::addr_t cmd_ptr = NULL; - PrepareToExecuteJITExpression (error_stream, exe_ctx, struct_address, object_ptr); + if (!PrepareToExecuteJITExpression (error_stream, exe_ctx, struct_address, object_ptr)) + return Process::eExecutionSetupError; const bool stop_others = true; const bool try_all_threads = true; Address wrapper_address (NULL, m_jit_addr); - lldb::ThreadPlanSP call_plan_sp(new ThreadPlanCallUserExpression (*(exe_ctx.thread), wrapper_address, struct_address, - stop_others, discard_on_error, - (m_needs_object_ptr ? &object_ptr : NULL), - shared_ptr_to_me)); + lldb::ThreadPlanSP call_plan_sp(new ThreadPlanCallUserExpression (*(exe_ctx.thread), + wrapper_address, + struct_address, + stop_others, + discard_on_error, + (m_needs_object_ptr ? &object_ptr : NULL), + ((m_needs_object_ptr && m_objectivec) ? &cmd_ptr : NULL), + shared_ptr_to_me)); + if (call_plan_sp == NULL || !call_plan_sp->ValidatePlan (NULL)) return Process::eExecutionSetupError; |