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.
git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@146806 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Target/ThreadPlanStepOut.cpp b/source/Target/ThreadPlanStepOut.cpp
index d78411e..485db25 100644
--- a/source/Target/ThreadPlanStepOut.cpp
+++ b/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 @@
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 @@
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 @@
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 @@
{
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 @@
}
else if (m_stack_depth > m_thread.GetStackFrameCount())
{
+ CalculateReturnValue();
SetPlanComplete();
return true;
}
@@ -233,6 +250,7 @@
}
else
{
+ CalculateReturnValue();
SetPlanComplete ();
return true;
}
@@ -244,6 +262,10 @@
{
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 @@
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);
+ }
+ }
+ }
+}