diff options
author | Jim Ingham <jingham@apple.com> | 2011-12-22 19:12:40 +0000 |
---|---|---|
committer | Jim Ingham <jingham@apple.com> | 2011-12-22 19:12:40 +0000 |
commit | ef651600167a47060e4b19bdb788a0d1649671b8 (patch) | |
tree | aabe5d4cfbeb06df5596ec5731c1d5e5f1485760 /lldb/source/Target | |
parent | 6901c0de675f3c264d496cdd75ac08fd21109305 (diff) | |
download | bcm5719-llvm-ef651600167a47060e4b19bdb788a0d1649671b8.tar.gz bcm5719-llvm-ef651600167a47060e4b19bdb788a0d1649671b8.zip |
Improve the x86_64 return value decoder to handle most structure returns.
Switch from GetReturnValue, which was hardly ever used, to GetReturnValueObject
which is much more convenient.
Return the "return value object" as a persistent variable if requested.
llvm-svn: 147157
Diffstat (limited to 'lldb/source/Target')
-rw-r--r-- | lldb/source/Target/ABI.cpp | 69 | ||||
-rw-r--r-- | lldb/source/Target/Thread.cpp | 2 | ||||
-rw-r--r-- | lldb/source/Target/ThreadPlanCallFunction.cpp | 13 | ||||
-rw-r--r-- | lldb/source/Target/ThreadPlanCallUserExpression.cpp | 2 |
4 files changed, 67 insertions, 19 deletions
diff --git a/lldb/source/Target/ABI.cpp b/lldb/source/Target/ABI.cpp index f3a5404aa10..7d82ab17bc7 100644 --- a/lldb/source/Target/ABI.cpp +++ b/lldb/source/Target/ABI.cpp @@ -12,6 +12,7 @@ #include "lldb/Core/Value.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/Symbol/ClangASTType.h" +#include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" using namespace lldb; @@ -104,25 +105,69 @@ ABI::GetRegisterInfoByKind (RegisterKind reg_kind, uint32_t reg_num, RegisterInf ValueObjectSP ABI::GetReturnValueObject (Thread &thread, - ClangASTType &ast_type) const + ClangASTType &ast_type, + bool persistent) const { if (!ast_type.IsValid()) return ValueObjectSP(); - Value ret_value; - ret_value.SetContext(Value::eContextTypeClangType, - ast_type.GetOpaqueQualType()); - if (GetReturnValue (thread, ret_value)) + ValueObjectSP return_valobj_sp; + + return_valobj_sp = GetReturnValueObjectImpl(thread, ast_type); + if (!return_valobj_sp) + return return_valobj_sp; + + // Now turn this into a persistent variable. + // FIXME: This code is duplicated from Target::EvaluateExpression, and it is used in similar form in a couple + // of other places. Figure out the correct Create function to do all this work. + + if (persistent) { - return ValueObjectConstResult::Create( - thread.GetStackFrameAtIndex(0).get(), - ast_type.GetASTContext(), - ret_value, - ConstString("FunctionReturn")); + ClangPersistentVariables& persistent_variables = thread.GetProcess().GetTarget().GetPersistentVariables(); + ConstString persistent_variable_name (persistent_variables.GetNextPersistentVariableName()); + + lldb::ValueObjectSP const_valobj_sp; + + // Check in case our value is already a constant value + if (return_valobj_sp->GetIsConstant()) + { + const_valobj_sp = return_valobj_sp; + const_valobj_sp->SetName (persistent_variable_name); + } + else + const_valobj_sp = return_valobj_sp->CreateConstantValue (persistent_variable_name); + + lldb::ValueObjectSP live_valobj_sp = return_valobj_sp; + + return_valobj_sp = const_valobj_sp; + + ClangExpressionVariableSP clang_expr_variable_sp(persistent_variables.CreatePersistentVariable(return_valobj_sp)); + + assert (clang_expr_variable_sp.get()); + + // Set flags and live data as appropriate + + const Value &result_value = live_valobj_sp->GetValue(); + + switch (result_value.GetValueType()) + { + case Value::eValueTypeHostAddress: + case Value::eValueTypeFileAddress: + // we don't do anything with these for now + break; + case Value::eValueTypeScalar: + clang_expr_variable_sp->m_flags |= ClangExpressionVariable::EVIsLLDBAllocated; + clang_expr_variable_sp->m_flags |= ClangExpressionVariable::EVNeedsAllocation; + break; + case Value::eValueTypeLoadAddress: + clang_expr_variable_sp->m_live_sp = live_valobj_sp; + clang_expr_variable_sp->m_flags |= ClangExpressionVariable::EVIsProgramReference; + break; + } + return_valobj_sp = clang_expr_variable_sp->GetValueObject(); } - else - return ValueObjectSP(); + return return_valobj_sp; } diff --git a/lldb/source/Target/Thread.cpp b/lldb/source/Target/Thread.cpp index 6fe6ec7df5b..ae083c770e3 100644 --- a/lldb/source/Target/Thread.cpp +++ b/lldb/source/Target/Thread.cpp @@ -861,7 +861,7 @@ Thread::QueueThreadPlanForCallFunction (bool abort_other_plans, bool stop_other_threads, bool discard_on_error) { - ThreadPlanSP thread_plan_sp (new ThreadPlanCallFunction (*this, function, arg, stop_other_threads, discard_on_error)); + ThreadPlanSP thread_plan_sp (new ThreadPlanCallFunction (*this, function, ClangASTType(), arg, stop_other_threads, discard_on_error)); QueueThreadPlan (thread_plan_sp, abort_other_plans); return thread_plan_sp.get(); } diff --git a/lldb/source/Target/ThreadPlanCallFunction.cpp b/lldb/source/Target/ThreadPlanCallFunction.cpp index 2494c7cacfd..a5180613f9e 100644 --- a/lldb/source/Target/ThreadPlanCallFunction.cpp +++ b/lldb/source/Target/ThreadPlanCallFunction.cpp @@ -37,6 +37,7 @@ using namespace lldb_private; ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread, Address &function, + const ClangASTType &return_type, addr_t arg, bool stop_other_threads, bool discard_on_error, @@ -47,6 +48,7 @@ ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread, m_stop_other_threads (stop_other_threads), m_function_addr (function), m_function_sp (NULL), + m_return_type (return_type), m_takedown_done (false), m_stop_address (LLDB_INVALID_ADDRESS) { @@ -149,6 +151,7 @@ ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread, ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread, Address &function, + const ClangASTType &return_type, bool stop_other_threads, bool discard_on_error, addr_t *arg1_ptr, @@ -162,6 +165,7 @@ ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread, m_stop_other_threads (stop_other_threads), m_function_addr (function), m_function_sp(NULL), + m_return_type (return_type), m_takedown_done (false) { SetOkayToDiscard (discard_on_error); @@ -281,13 +285,12 @@ ThreadPlanCallFunction::DoTakedown () LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); if (!m_takedown_done) { - // TODO: how do we tell if all went well? - if (m_return_value_sp) + const ABI *abi = m_thread.GetProcess().GetABI().get(); + if (abi && m_return_type.IsValid()) { - const ABI *abi = m_thread.GetProcess().GetABI().get(); - if (abi) - abi->GetReturnValue(m_thread, *m_return_value_sp); + m_return_valobj_sp = abi->GetReturnValueObject (m_thread, m_return_type); } + if (log) log->Printf ("DoTakedown called for thread 0x%4.4llx, m_valid: %d complete: %d.\n", m_thread.GetID(), m_valid, IsPlanComplete()); m_takedown_done = true; diff --git a/lldb/source/Target/ThreadPlanCallUserExpression.cpp b/lldb/source/Target/ThreadPlanCallUserExpression.cpp index 0499a7c7ce4..6352edb5311 100644 --- a/lldb/source/Target/ThreadPlanCallUserExpression.cpp +++ b/lldb/source/Target/ThreadPlanCallUserExpression.cpp @@ -44,7 +44,7 @@ ThreadPlanCallUserExpression::ThreadPlanCallUserExpression (Thread &thread, lldb::addr_t *this_arg, lldb::addr_t *cmd_arg, ClangUserExpression::ClangUserExpressionSP &user_expression_sp) : - ThreadPlanCallFunction (thread, function, arg, stop_other_threads, discard_on_error, this_arg, cmd_arg), + ThreadPlanCallFunction (thread, function, ClangASTType(), arg, stop_other_threads, discard_on_error, this_arg, cmd_arg), m_user_expression_sp (user_expression_sp) { } |