summaryrefslogtreecommitdiffstats
path: root/lldb/source
diff options
context:
space:
mode:
authorJim Ingham <jingham@apple.com>2011-12-17 01:35:57 +0000
committerJim Ingham <jingham@apple.com>2011-12-17 01:35:57 +0000
commit73ca05a2a0c6ce957f9679e76b35ee06dc1559d4 (patch)
tree20b0f08ba2a6812f994fdea521bf436ea25453ce /lldb/source
parent903231bc58b27bbd1b74622b013fa277ceaeb16f (diff)
downloadbcm5719-llvm-73ca05a2a0c6ce957f9679e76b35ee06dc1559d4.tar.gz
bcm5719-llvm-73ca05a2a0c6ce957f9679e76b35ee06dc1559d4.zip
Add the ability to capture the return value in a thread's stop info, and print it
as part of the thread format output. Currently this is only done for the ThreadPlanStepOut. Add a convenience API ABI::GetReturnValueObject. Change the ValueObject::EvaluationPoint to BE an ExecutionContextScope, rather than trying to hand out one of its subsidiary object's pointers. That way this will always be good. llvm-svn: 146806
Diffstat (limited to 'lldb/source')
-rw-r--r--lldb/source/API/SBThread.cpp28
-rw-r--r--lldb/source/API/SBValue.cpp12
-rw-r--r--lldb/source/Commands/CommandObjectThread.cpp2
-rw-r--r--lldb/source/Core/Debugger.cpp18
-rw-r--r--lldb/source/Core/ValueObject.cpp70
-rw-r--r--lldb/source/Core/ValueObjectConstResult.cpp24
-rw-r--r--lldb/source/Core/ValueObjectConstResultImpl.cpp2
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp2
-rw-r--r--lldb/source/Target/ABI.cpp29
-rw-r--r--lldb/source/Target/StopInfo.cpp28
-rw-r--r--lldb/source/Target/Thread.cpp18
-rw-r--r--lldb/source/Target/ThreadPlanStepOut.cpp47
12 files changed, 247 insertions, 33 deletions
diff --git a/lldb/source/API/SBThread.cpp b/lldb/source/API/SBThread.cpp
index 69924ad6ad0..9ea28772978 100644
--- a/lldb/source/API/SBThread.cpp
+++ b/lldb/source/API/SBThread.cpp
@@ -31,10 +31,10 @@
#include "lldb/API/SBAddress.h"
-#include "lldb/API/SBFrame.h"
-// DONT THINK THIS IS NECESSARY: #include "lldb/API/SBSourceManager.h"
#include "lldb/API/SBDebugger.h"
+#include "lldb/API/SBFrame.h"
#include "lldb/API/SBProcess.h"
+#include "lldb/API/SBValue.h"
using namespace lldb;
using namespace lldb_private;
@@ -316,6 +316,30 @@ SBThread::GetStopDescription (char *dst, size_t dst_len)
return 0;
}
+SBValue
+SBThread::GetStopReturnValue ()
+{
+ ValueObjectSP return_valobj_sp;
+ if (m_opaque_sp)
+ {
+ Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex());
+ StopInfoSP stop_info_sp = m_opaque_sp->GetStopInfo ();
+ if (stop_info_sp)
+ {
+ return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp);
+ }
+ }
+
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+ if (log)
+ log->Printf ("SBThread(%p)::GetStopReturnValue () => %s", m_opaque_sp.get(),
+ return_valobj_sp.get()
+ ? return_valobj_sp->GetValueAsCString()
+ : "<no return value>");
+
+ return SBValue (return_valobj_sp);
+}
+
void
SBThread::SetThread (const ThreadSP& lldb_object_sp)
{
diff --git a/lldb/source/API/SBValue.cpp b/lldb/source/API/SBValue.cpp
index c9f78e2cf1f..daaeea089ca 100644
--- a/lldb/source/API/SBValue.cpp
+++ b/lldb/source/API/SBValue.cpp
@@ -380,7 +380,7 @@ SBValue::CreateValueFromExpression (const char *name, const char* expression)
{
ValueObjectSP result_valobj_sp;
m_opaque_sp->GetUpdatePoint().GetTargetSP()->EvaluateExpression (expression,
- m_opaque_sp->GetUpdatePoint().GetExecutionContextScope()->CalculateStackFrame(),
+ m_opaque_sp->GetExecutionContextScope()->CalculateStackFrame(),
eExecutionPolicyOnlyWhenNeeded,
true, // unwind on error
true, // keep in memory
@@ -410,7 +410,7 @@ SBValue::CreateValueFromAddress(const char* name, lldb::addr_t address, SBType t
lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(&address,sizeof(lldb::addr_t)));
- ValueObjectSP ptr_result_valobj_sp(ValueObjectConstResult::Create (m_opaque_sp->GetUpdatePoint().GetExecutionContextScope(),
+ ValueObjectSP ptr_result_valobj_sp(ValueObjectConstResult::Create (m_opaque_sp->GetExecutionContextScope(),
real_type.m_opaque_sp->GetASTContext(),
real_type.m_opaque_sp->GetOpaqueQualType(),
ConstString(name),
@@ -871,9 +871,9 @@ SBValue::GetThread()
SBThread result;
if (m_opaque_sp)
{
- if (m_opaque_sp->GetUpdatePoint().GetExecutionContextScope())
+ if (m_opaque_sp->GetExecutionContextScope())
{
- result = SBThread(m_opaque_sp->GetUpdatePoint().GetExecutionContextScope()->CalculateThread()->GetSP());
+ result = SBThread(m_opaque_sp->GetExecutionContextScope()->CalculateThread()->GetSP());
}
}
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
@@ -893,9 +893,9 @@ SBValue::GetFrame()
SBFrame result;
if (m_opaque_sp)
{
- if (m_opaque_sp->GetUpdatePoint().GetExecutionContextScope())
+ if (m_opaque_sp->GetExecutionContextScope())
{
- result.SetFrame (m_opaque_sp->GetUpdatePoint().GetExecutionContextScope()->CalculateStackFrame()->GetSP());
+ result.SetFrame (m_opaque_sp->GetExecutionContextScope()->CalculateStackFrame()->GetSP());
}
}
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
diff --git a/lldb/source/Commands/CommandObjectThread.cpp b/lldb/source/Commands/CommandObjectThread.cpp
index 658222e19d8..d6a9670fe0f 100644
--- a/lldb/source/Commands/CommandObjectThread.cpp
+++ b/lldb/source/Commands/CommandObjectThread.cpp
@@ -1246,7 +1246,7 @@ CommandObjectMultiwordThread::CommandObjectMultiwordThread (CommandInterpreter &
LoadSubCommand ("step-out", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
interpreter,
"thread step-out",
- "Finish executing the current function and return to its call site in specified thread (current thread, if none specified).",
+ "Finish executing the function of the currently selected frame and return to its call site in specified thread (current thread, if none specified).",
NULL,
eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
eStepTypeOut,
diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp
index cd86698661a..e33e9412c91 100644
--- a/lldb/source/Core/Debugger.cpp
+++ b/lldb/source/Core/Debugger.cpp
@@ -1701,6 +1701,23 @@ Debugger::FormatPrompt
}
}
}
+ else if (::strncmp (var_name_begin, "return-value}", strlen("return-value}")) == 0)
+ {
+ StopInfoSP stop_info_sp = thread->GetStopInfo ();
+ if (stop_info_sp)
+ {
+ ValueObjectSP return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp);
+ if (return_valobj_sp)
+ {
+ cstr = return_valobj_sp->GetValueAsCString ();
+ if (cstr && cstr[0])
+ {
+ s.PutCString(cstr);
+ var_success = true;
+ }
+ }
+ }
+ }
}
}
}
@@ -2562,6 +2579,7 @@ Debugger::SettingsController::global_settings_table[] =
MODULE_WITH_FUNC\
FILE_AND_LINE\
"{, stop reason = ${thread.stop-reason}}"\
+ "{, return value = ${thread.return-value}}"\
"\\n"
//#define DEFAULT_THREAD_FORMAT "thread #${thread.index}: tid = ${thread.id}"\
diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp
index 657faf36f85..e1c25becbc7 100644
--- a/lldb/source/Core/ValueObject.cpp
+++ b/lldb/source/Core/ValueObject.cpp
@@ -707,7 +707,7 @@ ValueObject::GetPointeeData (DataExtractor& data,
AddressType addr_type;
lldb::addr_t addr = IsPointerType() ? GetPointerValue(&addr_type) : GetAddressOf(true, &addr_type);
- ExecutionContextScope *exe_scope = m_update_point.GetExecutionContextScope();
+ ExecutionContextScope *exe_scope = GetExecutionContextScope();
switch (addr_type)
@@ -3428,12 +3428,14 @@ ValueObject::CastPointerType (const char *name, TypeSP &type_sp)
}
ValueObject::EvaluationPoint::EvaluationPoint () :
+ ExecutionContextScope(),
m_thread_id (LLDB_INVALID_UID),
m_mod_id ()
{
}
ValueObject::EvaluationPoint::EvaluationPoint (ExecutionContextScope *exe_scope, bool use_selected):
+ ExecutionContextScope (),
m_needs_update (true),
m_first_update (true),
m_thread_id (LLDB_INVALID_THREAD_ID),
@@ -3500,14 +3502,47 @@ ValueObject::EvaluationPoint::~EvaluationPoint ()
{
}
-ExecutionContextScope *
-ValueObject::EvaluationPoint::GetExecutionContextScope ()
+Target *
+ValueObject::EvaluationPoint::CalculateTarget ()
{
- // We have to update before giving out the scope, or we could be handing out stale pointers.
- ExecutionContextScope *exe_scope;
+ return m_target_sp.get();
+}
+
+Process *
+ValueObject::EvaluationPoint::CalculateProcess ()
+{
+ return m_process_sp.get();
+}
+
+Thread *
+ValueObject::EvaluationPoint::CalculateThread ()
+{
+ ExecutionContextScope *exe_scope;
SyncWithProcessState(exe_scope);
-
- return exe_scope;
+ if (exe_scope)
+ return exe_scope->CalculateThread();
+ else
+ return NULL;
+}
+
+StackFrame *
+ValueObject::EvaluationPoint::CalculateStackFrame ()
+{
+ ExecutionContextScope *exe_scope;
+ SyncWithProcessState(exe_scope);
+ if (exe_scope)
+ return exe_scope->CalculateStackFrame();
+ else
+ return NULL;
+}
+
+void
+ValueObject::EvaluationPoint::CalculateExecutionContext (ExecutionContext &exe_ctx)
+{
+ ExecutionContextScope *exe_scope;
+ SyncWithProcessState(exe_scope);
+ if (exe_scope)
+ return exe_scope->CalculateExecutionContext (exe_ctx);
}
// This function checks the EvaluationPoint against the current process state. If the current
@@ -3520,12 +3555,18 @@ ValueObject::EvaluationPoint::GetExecutionContextScope ()
bool
ValueObject::EvaluationPoint::SyncWithProcessState(ExecutionContextScope *&exe_scope)
{
+
+ // Start with the target, if it is NULL, then we're obviously not going to get any further:
+ exe_scope = m_target_sp.get();
+
+ if (exe_scope == NULL)
+ return false;
+
// If we don't have a process nothing can change.
if (!m_process_sp)
- {
- exe_scope = m_target_sp.get();
return false;
- }
+
+ exe_scope = m_process_sp.get();
// If our stop id is the current stop ID, nothing has changed:
ProcessModID current_mod_id = m_process_sp->GetModID();
@@ -3533,10 +3574,7 @@ ValueObject::EvaluationPoint::SyncWithProcessState(ExecutionContextScope *&exe_s
// If the current stop id is 0, either we haven't run yet, or the process state has been cleared.
// In either case, we aren't going to be able to sync with the process state.
if (current_mod_id.GetStopID() == 0)
- {
- exe_scope = m_target_sp.get();
return false;
- }
bool changed;
@@ -3555,10 +3593,10 @@ ValueObject::EvaluationPoint::SyncWithProcessState(ExecutionContextScope *&exe_s
changed = true;
}
}
- exe_scope = m_process_sp.get();
- // Something has changed, so we will return true. Now make sure the thread & frame still exist, and if either
- // doesn't, mark ourselves as invalid.
+ // Now re-look up the thread and frame in case the underlying objects have gone away & been recreated.
+ // That way we'll be sure to return a valid exe_scope.
+ // If we used to have a thread or a frame but can't find it anymore, then mark ourselves as invalid.
if (m_thread_id != LLDB_INVALID_THREAD_ID)
{
diff --git a/lldb/source/Core/ValueObjectConstResult.cpp b/lldb/source/Core/ValueObjectConstResult.cpp
index fa1503f3217..950d33405af 100644
--- a/lldb/source/Core/ValueObjectConstResult.cpp
+++ b/lldb/source/Core/ValueObjectConstResult.cpp
@@ -130,6 +130,15 @@ ValueObjectConstResult::Create
address))->GetSP();
}
+ValueObjectSP
+ValueObjectConstResult::Create (ExecutionContextScope *exe_scope,
+ clang::ASTContext *clang_ast,
+ Value &value,
+ const ConstString &name)
+{
+ return (new ValueObjectConstResult (exe_scope, clang_ast, value, name))->GetSP();
+}
+
ValueObjectConstResult::ValueObjectConstResult
(
ExecutionContextScope *exe_scope,
@@ -239,6 +248,21 @@ ValueObjectConstResult::ValueObjectConstResult (
SetIsConstant ();
}
+ValueObjectConstResult::ValueObjectConstResult (
+ ExecutionContextScope *exe_scope,
+ clang::ASTContext *clang_ast,
+ const Value &value,
+ const ConstString &name) :
+ ValueObject (exe_scope),
+ m_type_name (),
+ m_byte_size (0),
+ m_clang_ast (clang_ast),
+ m_impl(this)
+{
+ m_value = value;
+ m_value.GetData(m_data);
+}
+
ValueObjectConstResult::~ValueObjectConstResult()
{
}
diff --git a/lldb/source/Core/ValueObjectConstResultImpl.cpp b/lldb/source/Core/ValueObjectConstResultImpl.cpp
index afe050291b0..31646b4ca0b 100644
--- a/lldb/source/Core/ValueObjectConstResultImpl.cpp
+++ b/lldb/source/Core/ValueObjectConstResultImpl.cpp
@@ -185,7 +185,7 @@ ValueObjectConstResultImpl::AddressOf (Error &error)
std::string new_name("&");
new_name.append(m_impl_backend->GetName().AsCString(""));
- m_address_of_backend = ValueObjectConstResult::Create(m_impl_backend->GetUpdatePoint().GetExecutionContextScope(),
+ m_address_of_backend = ValueObjectConstResult::Create(m_impl_backend->GetExecutionContextScope(),
type.GetASTContext(),
type.GetPointerType(),
ConstString(new_name.c_str()),
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
index 4119c6e5273..1094dc1e34c 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
@@ -309,7 +309,7 @@ AppleObjCRuntimeV2::GetDynamicTypeAndAddress (ValueObject &in_value,
// If the class address didn't point into the binary, or
// it points into the right section but there wasn't a symbol
// there, try to look it up by calling the class method in the target.
- ExecutionContextScope *exe_scope = in_value.GetUpdatePoint().GetExecutionContextScope();
+ ExecutionContextScope *exe_scope = in_value.GetExecutionContextScope();
Thread *thread_to_use;
if (exe_scope)
thread_to_use = exe_scope->CalculateThread();
diff --git a/lldb/source/Target/ABI.cpp b/lldb/source/Target/ABI.cpp
index fc55ccac6fc..f3a5404aa10 100644
--- a/lldb/source/Target/ABI.cpp
+++ b/lldb/source/Target/ABI.cpp
@@ -9,6 +9,10 @@
#include "lldb/Target/ABI.h"
#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Value.h"
+#include "lldb/Core/ValueObjectConstResult.h"
+#include "lldb/Symbol/ClangASTType.h"
+#include "lldb/Target/Thread.h"
using namespace lldb;
using namespace lldb_private;
@@ -97,3 +101,28 @@ ABI::GetRegisterInfoByKind (RegisterKind reg_kind, uint32_t reg_num, RegisterInf
}
return false;
}
+
+ValueObjectSP
+ABI::GetReturnValueObject (Thread &thread,
+ ClangASTType &ast_type) const
+{
+ if (!ast_type.IsValid())
+ return ValueObjectSP();
+
+ Value ret_value;
+ ret_value.SetContext(Value::eContextTypeClangType,
+ ast_type.GetOpaqueQualType());
+ if (GetReturnValue (thread, ret_value))
+ {
+ return ValueObjectConstResult::Create(
+ thread.GetStackFrameAtIndex(0).get(),
+ ast_type.GetASTContext(),
+ ret_value,
+ ConstString("FunctionReturn"));
+
+ }
+ else
+ return ValueObjectSP();
+}
+
+
diff --git a/lldb/source/Target/StopInfo.cpp b/lldb/source/Target/StopInfo.cpp
index 4e089d42c05..f90968fdad7 100644
--- a/lldb/source/Target/StopInfo.cpp
+++ b/lldb/source/Target/StopInfo.cpp
@@ -722,9 +722,10 @@ class StopInfoThreadPlan : public StopInfo
{
public:
- StopInfoThreadPlan (ThreadPlanSP &plan_sp) :
+ StopInfoThreadPlan (ThreadPlanSP &plan_sp, ValueObjectSP &return_valobj_sp) :
StopInfo (plan_sp->GetThread(), LLDB_INVALID_UID),
- m_plan_sp (plan_sp)
+ m_plan_sp (plan_sp),
+ m_return_valobj_sp (return_valobj_sp)
{
}
@@ -749,9 +750,16 @@ public:
}
return m_description.c_str();
}
+
+ ValueObjectSP
+ GetReturnValueObject()
+ {
+ return m_return_valobj_sp;
+ }
private:
ThreadPlanSP m_plan_sp;
+ ValueObjectSP m_return_valobj_sp;
};
} // namespace lldb_private
@@ -786,9 +794,9 @@ StopInfo::CreateStopReasonToTrace (Thread &thread)
}
StopInfoSP
-StopInfo::CreateStopReasonWithPlan (ThreadPlanSP &plan_sp)
+StopInfo::CreateStopReasonWithPlan (ThreadPlanSP &plan_sp, ValueObjectSP return_valobj_sp)
{
- return StopInfoSP (new StopInfoThreadPlan (plan_sp));
+ return StopInfoSP (new StopInfoThreadPlan (plan_sp, return_valobj_sp));
}
StopInfoSP
@@ -796,3 +804,15 @@ StopInfo::CreateStopReasonWithException (Thread &thread, const char *description
{
return StopInfoSP (new StopInfoException (thread, description));
}
+
+ValueObjectSP
+StopInfo::GetReturnValueObject(StopInfoSP &stop_info_sp)
+{
+ if (stop_info_sp && stop_info_sp->GetStopReason() == eStopReasonPlanComplete)
+ {
+ StopInfoThreadPlan *plan_stop_info = static_cast<StopInfoThreadPlan *>(stop_info_sp.get());
+ return plan_stop_info->GetReturnValueObject();
+ }
+ else
+ return ValueObjectSP();
+}
diff --git a/lldb/source/Target/Thread.cpp b/lldb/source/Target/Thread.cpp
index e4415b7b73e..6fe6ec7df5b 100644
--- a/lldb/source/Target/Thread.cpp
+++ b/lldb/source/Target/Thread.cpp
@@ -95,7 +95,7 @@ Thread::GetStopInfo ()
{
ThreadPlanSP plan_sp (GetCompletedPlan());
if (plan_sp)
- return StopInfo::CreateStopReasonWithPlan (plan_sp);
+ return StopInfo::CreateStopReasonWithPlan (plan_sp, GetReturnValueObject());
else
{
if (m_actual_stop_info_sp
@@ -551,6 +551,22 @@ Thread::GetCompletedPlan ()
return empty_plan_sp;
}
+ValueObjectSP
+Thread::GetReturnValueObject ()
+{
+ if (!m_completed_plan_stack.empty())
+ {
+ for (int i = m_completed_plan_stack.size() - 1; i >= 0; i--)
+ {
+ ValueObjectSP return_valobj_sp;
+ return_valobj_sp = m_completed_plan_stack[i]->GetReturnValueObject();
+ if (return_valobj_sp)
+ return return_valobj_sp;
+ }
+ }
+ return ValueObjectSP();
+}
+
bool
Thread::IsThreadPlanDone (ThreadPlan *plan)
{
diff --git a/lldb/source/Target/ThreadPlanStepOut.cpp b/lldb/source/Target/ThreadPlanStepOut.cpp
index d78411ee936..485db25dd8d 100644
--- a/lldb/source/Target/ThreadPlanStepOut.cpp
+++ b/lldb/source/Target/ThreadPlanStepOut.cpp
@@ -16,6 +16,8 @@
#include "lldb/Breakpoint/Breakpoint.h"
#include "lldb/lldb-private-log.h"
#include "lldb/Core/Log.h"
+#include "lldb/Core/Value.h"
+#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StopInfo.h"
@@ -47,7 +49,8 @@ ThreadPlanStepOut::ThreadPlanStepOut
m_first_insn (first_insn),
m_stop_others (stop_others),
m_step_through_inline_plan_sp(),
- m_step_out_plan_sp ()
+ m_step_out_plan_sp (),
+ m_immediate_step_from_function(NULL)
{
m_step_from_insn = m_thread.GetRegisterContext()->GetPC(0);
@@ -88,6 +91,15 @@ ThreadPlanStepOut::ThreadPlanStepOut
return_bp->SetThreadID(m_thread.GetID());
m_return_bp_id = return_bp->GetID();
}
+
+ if (immediate_return_from_sp)
+ {
+ const SymbolContext &sc = immediate_return_from_sp->GetSymbolContext(eSymbolContextFunction);
+ if (sc.function)
+ {
+ m_immediate_step_from_function = sc.function;
+ }
+ }
}
}
@@ -152,6 +164,7 @@ ThreadPlanStepOut::PlanExplainsStop ()
if (m_step_out_plan_sp->MischiefManaged())
{
// If this one is done, then we are all done.
+ CalculateReturnValue();
SetPlanComplete();
return true;
}
@@ -183,7 +196,10 @@ ThreadPlanStepOut::PlanExplainsStop ()
{
const uint32_t num_frames = m_thread.GetStackFrameCount();
if (m_stack_depth > num_frames)
+ {
+ CalculateReturnValue();
SetPlanComplete();
+ }
// If there was only one owner, then we're done. But if we also hit some
// user breakpoint on our way out, we should mark ourselves as done, but
@@ -217,6 +233,7 @@ ThreadPlanStepOut::ShouldStop (Event *event_ptr)
}
else if (m_stack_depth > m_thread.GetStackFrameCount())
{
+ CalculateReturnValue();
SetPlanComplete();
return true;
}
@@ -233,6 +250,7 @@ ThreadPlanStepOut::ShouldStop (Event *event_ptr)
}
else
{
+ CalculateReturnValue();
SetPlanComplete ();
return true;
}
@@ -244,6 +262,10 @@ ThreadPlanStepOut::ShouldStop (Event *event_ptr)
{
if (m_step_through_inline_plan_sp->MischiefManaged())
{
+ // We don't calculate the return value here because we don't know how to.
+ // But in case we had a return value sitting around from our process in
+ // getting here, let's clear it out.
+ m_return_valobj_sp.reset();
SetPlanComplete();
return true;
}
@@ -387,3 +409,26 @@ ThreadPlanStepOut::QueueInlinedStepPlan (bool queue_now)
return false;
}
+
+void
+ThreadPlanStepOut::CalculateReturnValue ()
+{
+ if (m_return_valobj_sp)
+ return;
+
+ if (m_immediate_step_from_function != NULL)
+ {
+ Type *return_type = m_immediate_step_from_function->GetType();
+ lldb::clang_type_t return_clang_type = m_immediate_step_from_function->GetReturnClangType();
+ if (return_type && return_clang_type)
+ {
+ ClangASTType ast_type (return_type->GetClangAST(), return_clang_type);
+
+ lldb::ABISP abi_sp = m_thread.GetProcess().GetABI();
+ if (abi_sp)
+ {
+ m_return_valobj_sp = abi_sp->GetReturnValueObject(m_thread, ast_type);
+ }
+ }
+ }
+}
OpenPOWER on IntegriCloud