Start at getting "thread return" working.  Doesn't work yet.


git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@163670 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Target/Thread.cpp b/source/Target/Thread.cpp
index 05ab150..72c5261 100644
--- a/source/Target/Thread.cpp
+++ b/source/Target/Thread.cpp
@@ -1271,6 +1271,62 @@
     return GetStackFrameList()->GetFrameWithConcreteFrameIndex (unwind_idx);
 }
 
+
+Error
+Thread::ReturnToFrameWithIndex (uint32_t frame_idx, lldb::ValueObjectSP return_value_sp)
+{
+    StackFrameSP frame_sp = GetStackFrameAtIndex (frame_idx);
+    Error return_error;
+    
+    if (!frame_sp)
+    {
+        return_error.SetErrorStringWithFormat("Could not find frame with index %d in thread 0x%llx.", frame_idx, GetID());
+    }
+    
+    return ReturnToFrame(frame_sp, return_value_sp);
+}
+
+Error
+Thread::ReturnToFrame (lldb::StackFrameSP frame_sp, lldb::ValueObjectSP return_value_sp)
+{
+    Error return_error;
+    
+    if (!frame_sp)
+    {
+        return_error.SetErrorString("Can't return to a null frame.");
+        return return_error;
+    }
+    
+    Thread *thread = frame_sp->GetThread().get();
+    
+    if (return_value_sp)
+    {
+        lldb::ABISP abi = thread->GetProcess()->GetABI();
+        if (!abi)
+        {
+            return_error.SetErrorString("Could not find ABI to set return value.");
+        }
+        return_error = abi->SetReturnValueObject(frame_sp, return_value_sp);
+        if (!return_error.Success())
+            return return_error;
+    }
+    
+    // Now write the return registers for the chosen frame:
+    lldb::DataBufferSP register_values_sp;
+    frame_sp->GetRegisterContext()->ReadAllRegisterValues (register_values_sp);
+    if (thread->ResetFrameZeroRegisters(register_values_sp))
+    {
+        thread->DiscardThreadPlans(true);
+        return return_error;
+    }
+    else
+    {
+        return_error.SetErrorString("Could not reset register values.");
+        return return_error;
+    
+    }
+}
+
 void
 Thread::DumpUsingSettingsFormat (Stream &strm, uint32_t frame_idx)
 {
@@ -1430,10 +1486,16 @@
 bool
 Thread::RestoreSaveFrameZero (const RegisterCheckpoint &checkpoint)
 {
+    return ResetFrameZeroRegisters (checkpoint.GetData());
+}
+
+bool
+Thread::ResetFrameZeroRegisters (lldb::DataBufferSP register_data_sp)
+{
     lldb::StackFrameSP frame_sp(GetStackFrameAtIndex (0));
     if (frame_sp)
     {
-        bool ret = frame_sp->GetRegisterContext()->WriteAllRegisterValues (checkpoint.GetData());
+        bool ret = frame_sp->GetRegisterContext()->WriteAllRegisterValues (register_data_sp);
 
         // Clear out all stack frames as our world just changed.
         ClearStackFrames();