[Lldb-commits] [lldb] r146806 - in /lldb/trunk: include/lldb/API/ include/lldb/Core/ include/lldb/Target/ scripts/Python/interface/ source/API/ source/Commands/ source/Core/ source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/ source/Target/ www/

Jim Ingham jingham at apple.com
Fri Dec 16 17:35:58 PST 2011


Author: jingham
Date: Fri Dec 16 19:35:57 2011
New Revision: 146806

URL: http://llvm.org/viewvc/llvm-project?rev=146806&view=rev
Log:
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.

Modified:
    lldb/trunk/include/lldb/API/SBThread.h
    lldb/trunk/include/lldb/Core/ValueObject.h
    lldb/trunk/include/lldb/Core/ValueObjectConstResult.h
    lldb/trunk/include/lldb/Target/ABI.h
    lldb/trunk/include/lldb/Target/StopInfo.h
    lldb/trunk/include/lldb/Target/Thread.h
    lldb/trunk/include/lldb/Target/ThreadPlan.h
    lldb/trunk/include/lldb/Target/ThreadPlanStepOut.h
    lldb/trunk/scripts/Python/interface/SBThread.i
    lldb/trunk/source/API/SBThread.cpp
    lldb/trunk/source/API/SBValue.cpp
    lldb/trunk/source/Commands/CommandObjectThread.cpp
    lldb/trunk/source/Core/Debugger.cpp
    lldb/trunk/source/Core/ValueObject.cpp
    lldb/trunk/source/Core/ValueObjectConstResult.cpp
    lldb/trunk/source/Core/ValueObjectConstResultImpl.cpp
    lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
    lldb/trunk/source/Target/ABI.cpp
    lldb/trunk/source/Target/StopInfo.cpp
    lldb/trunk/source/Target/Thread.cpp
    lldb/trunk/source/Target/ThreadPlanStepOut.cpp
    lldb/trunk/www/formats.html

Modified: lldb/trunk/include/lldb/API/SBThread.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBThread.h?rev=146806&r1=146805&r2=146806&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBThread.h (original)
+++ lldb/trunk/include/lldb/API/SBThread.h Fri Dec 16 19:35:57 2011
@@ -63,6 +63,9 @@
 
     size_t
     GetStopDescription (char *dst, size_t dst_len);
+    
+    SBValue
+    GetStopReturnValue ();
 
     lldb::tid_t
     GetThreadID () const;

Modified: lldb/trunk/include/lldb/Core/ValueObject.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObject.h?rev=146806&r1=146805&r2=146806&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/ValueObject.h (original)
+++ lldb/trunk/include/lldb/Core/ValueObject.h Fri Dec 16 19:35:57 2011
@@ -336,7 +336,7 @@
 
     };
 
-    class EvaluationPoint 
+    class EvaluationPoint : public ExecutionContextScope
     {
     public:
         
@@ -348,9 +348,6 @@
         
         ~EvaluationPoint ();
         
-        ExecutionContextScope *
-        GetExecutionContextScope ();
-                
         const lldb::TargetSP &
         GetTargetSP () const
         {
@@ -443,6 +440,20 @@
             
         }
         
+        // If this EvaluationPoint is created without a target, then we could have it
+        // hand out a NULL ExecutionContextScope.  But then everybody would have to check that before
+        // calling through it, which is annoying.  So instead, we make the EvaluationPoint BE an
+        // ExecutionContextScope, and it hands out the right things.
+        virtual Target *CalculateTarget ();
+        
+        virtual Process *CalculateProcess ();
+        
+        virtual Thread *CalculateThread ();
+        
+        virtual StackFrame *CalculateStackFrame ();
+        
+        virtual void CalculateExecutionContext (ExecutionContext &exe_ctx);
+        
     private:
         bool
         SyncWithProcessState ()
@@ -479,7 +490,7 @@
     ExecutionContextScope *
     GetExecutionContextScope ()
     {
-        return m_update_point.GetExecutionContextScope();
+        return &m_update_point;
     }
     
     void

Modified: lldb/trunk/include/lldb/Core/ValueObjectConstResult.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObjectConstResult.h?rev=146806&r1=146805&r2=146806&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/ValueObjectConstResult.h (original)
+++ lldb/trunk/include/lldb/Core/ValueObjectConstResult.h Fri Dec 16 19:35:57 2011
@@ -59,6 +59,12 @@
             AddressType address_type,
             uint8_t addr_byte_size);
 
+    static lldb::ValueObjectSP
+    Create (ExecutionContextScope *exe_scope,
+            clang::ASTContext *clang_ast,
+            Value &value,
+            const ConstString &name);
+
     // When an expression fails to evaluate, we return an error
     static lldb::ValueObjectSP
     Create (ExecutionContextScope *exe_scope,
@@ -181,6 +187,11 @@
                             uint8_t addr_byte_size);
 
     ValueObjectConstResult (ExecutionContextScope *exe_scope,
+                            clang::ASTContext *clang_ast,
+                            const Value &value,
+                            const ConstString &name);
+
+    ValueObjectConstResult (ExecutionContextScope *exe_scope,
                             const Error& error);
 
     DISALLOW_COPY_AND_ASSIGN (ValueObjectConstResult);

Modified: lldb/trunk/include/lldb/Target/ABI.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ABI.h?rev=146806&r1=146805&r2=146806&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/ABI.h (original)
+++ lldb/trunk/include/lldb/Target/ABI.h Fri Dec 16 19:35:57 2011
@@ -48,6 +48,10 @@
     virtual bool
     GetReturnValue (Thread &thread,
                     Value &value) const = 0;
+                    
+    virtual lldb::ValueObjectSP
+    GetReturnValueObject (Thread &thread,
+                          ClangASTType &type) const;
 
     virtual bool
     CreateFunctionEntryUnwindPlan (UnwindPlan &unwind_plan) = 0;

Modified: lldb/trunk/include/lldb/Target/StopInfo.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/StopInfo.h?rev=146806&r1=146805&r2=146806&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/StopInfo.h (original)
+++ lldb/trunk/include/lldb/Target/StopInfo.h Fri Dec 16 19:35:57 2011
@@ -126,10 +126,13 @@
     CreateStopReasonToTrace (Thread &thread);
 
     static lldb::StopInfoSP
-    CreateStopReasonWithPlan (lldb::ThreadPlanSP &plan);
+    CreateStopReasonWithPlan (lldb::ThreadPlanSP &plan, lldb::ValueObjectSP return_valobj_sp);
 
     static lldb::StopInfoSP
     CreateStopReasonWithException (Thread &thread, const char *description);
+    
+    static lldb::ValueObjectSP
+    GetReturnValueObject (lldb::StopInfoSP &stop_info_sp);
 
 protected:
     //------------------------------------------------------------------

Modified: lldb/trunk/include/lldb/Target/Thread.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Thread.h?rev=146806&r1=146805&r2=146806&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Thread.h (original)
+++ lldb/trunk/include/lldb/Target/Thread.h Fri Dec 16 19:35:57 2011
@@ -604,7 +604,7 @@
 public:
 
     //------------------------------------------------------------------
-    /// Gets the inner-most plan that was popped off the plan stack in the
+    /// Gets the outer-most plan that was popped off the plan stack in the
     /// most recent stop.  Useful for printing the stop reason accurately.
     ///
     /// @return
@@ -614,6 +614,16 @@
     GetCompletedPlan ();
 
     //------------------------------------------------------------------
+    /// Gets the outer-most return value from the completed plans
+    ///
+    /// @return
+    ///     A ValueObjectSP, either empty if there is no return value,
+    ///     or containing the return value.
+    //------------------------------------------------------------------
+    lldb::ValueObjectSP
+    GetReturnValueObject ();
+
+    //------------------------------------------------------------------
     ///  Checks whether the given plan is in the completed plans for this
     ///  stop.
     ///

Modified: lldb/trunk/include/lldb/Target/ThreadPlan.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ThreadPlan.h?rev=146806&r1=146805&r2=146806&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/ThreadPlan.h (original)
+++ lldb/trunk/include/lldb/Target/ThreadPlan.h Fri Dec 16 19:35:57 2011
@@ -387,6 +387,12 @@
         return m_thread.GetStopInfo ();
     }
     
+    virtual lldb::ValueObjectSP
+    GetReturnValueObject ()
+    {
+        return lldb::ValueObjectSP();
+    }
+    
 protected:
     //------------------------------------------------------------------
     // Classes that inherit from ThreadPlan can see and modify these

Modified: lldb/trunk/include/lldb/Target/ThreadPlanStepOut.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ThreadPlanStepOut.h?rev=146806&r1=146805&r2=146806&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/ThreadPlanStepOut.h (original)
+++ lldb/trunk/include/lldb/Target/ThreadPlanStepOut.h Fri Dec 16 19:35:57 2011
@@ -42,6 +42,11 @@
     virtual bool WillStop ();
     virtual bool MischiefManaged ();
     virtual void DidPush();
+    
+    virtual lldb::ValueObjectSP GetReturnValueObject()
+    {
+        return m_return_valobj_sp;
+    }
 
 protected:
     bool QueueInlinedStepPlan (bool queue_now);
@@ -56,6 +61,8 @@
     bool m_stop_others;
     lldb::ThreadPlanSP m_step_through_inline_plan_sp;
     lldb::ThreadPlanSP m_step_out_plan_sp;
+    Function          *m_immediate_step_from_function;
+    lldb::ValueObjectSP m_return_valobj_sp;
 
     friend ThreadPlan *
     Thread::QueueThreadPlanForStepOut (bool abort_other_plans,
@@ -69,6 +76,9 @@
     // Need an appropriate marker for the current stack so we can tell step out
     // from step in.
 
+    void
+    CalculateReturnValue();
+    
     DISALLOW_COPY_AND_ASSIGN (ThreadPlanStepOut);
 
 };

Modified: lldb/trunk/scripts/Python/interface/SBThread.i
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/interface/SBThread.i?rev=146806&r1=146805&r2=146806&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/interface/SBThread.i (original)
+++ lldb/trunk/scripts/Python/interface/SBThread.i Fri Dec 16 19:35:57 2011
@@ -82,6 +82,9 @@
     size_t
     GetStopDescription (char *dst, size_t dst_len);
 
+    SBValue
+    GetStopReturnValue ();
+
     lldb::tid_t
     GetThreadID () const;
 

Modified: lldb/trunk/source/API/SBThread.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBThread.cpp?rev=146806&r1=146805&r2=146806&view=diff
==============================================================================
--- lldb/trunk/source/API/SBThread.cpp (original)
+++ lldb/trunk/source/API/SBThread.cpp Fri Dec 16 19:35:57 2011
@@ -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 @@
     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)
 {

Modified: lldb/trunk/source/API/SBValue.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBValue.cpp?rev=146806&r1=146805&r2=146806&view=diff
==============================================================================
--- lldb/trunk/source/API/SBValue.cpp (original)
+++ lldb/trunk/source/API/SBValue.cpp Fri Dec 16 19:35:57 2011
@@ -380,7 +380,7 @@
     {
         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 @@
         
         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 @@
     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 @@
     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));

Modified: lldb/trunk/source/Commands/CommandObjectThread.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectThread.cpp?rev=146806&r1=146805&r2=146806&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectThread.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectThread.cpp Fri Dec 16 19:35:57 2011
@@ -1246,7 +1246,7 @@
     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,

Modified: lldb/trunk/source/Core/Debugger.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Debugger.cpp?rev=146806&r1=146805&r2=146806&view=diff
==============================================================================
--- lldb/trunk/source/Core/Debugger.cpp (original)
+++ lldb/trunk/source/Core/Debugger.cpp Fri Dec 16 19:35:57 2011
@@ -1701,6 +1701,23 @@
                                                 }
                                             }
                                         }
+                                        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 @@
     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}"\

Modified: lldb/trunk/source/Core/ValueObject.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObject.cpp?rev=146806&r1=146805&r2=146806&view=diff
==============================================================================
--- lldb/trunk/source/Core/ValueObject.cpp (original)
+++ lldb/trunk/source/Core/ValueObject.cpp Fri Dec 16 19:35:57 2011
@@ -707,7 +707,7 @@
         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::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 @@
 {
 }
 
-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 @@
 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 @@
     // 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 @@
             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)
     {

Modified: lldb/trunk/source/Core/ValueObjectConstResult.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObjectConstResult.cpp?rev=146806&r1=146805&r2=146806&view=diff
==============================================================================
--- lldb/trunk/source/Core/ValueObjectConstResult.cpp (original)
+++ lldb/trunk/source/Core/ValueObjectConstResult.cpp Fri Dec 16 19:35:57 2011
@@ -130,6 +130,15 @@
                                         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 @@
     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()
 {
 }

Modified: lldb/trunk/source/Core/ValueObjectConstResultImpl.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObjectConstResultImpl.cpp?rev=146806&r1=146805&r2=146806&view=diff
==============================================================================
--- lldb/trunk/source/Core/ValueObjectConstResultImpl.cpp (original)
+++ lldb/trunk/source/Core/ValueObjectConstResultImpl.cpp Fri Dec 16 19:35:57 2011
@@ -185,7 +185,7 @@
         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()),

Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp?rev=146806&r1=146805&r2=146806&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp Fri Dec 16 19:35:57 2011
@@ -309,7 +309,7 @@
             // 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();

Modified: lldb/trunk/source/Target/ABI.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ABI.cpp?rev=146806&r1=146805&r2=146806&view=diff
==============================================================================
--- lldb/trunk/source/Target/ABI.cpp (original)
+++ lldb/trunk/source/Target/ABI.cpp Fri Dec 16 19:35:57 2011
@@ -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 @@
     }
     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();
+}
+
+

Modified: lldb/trunk/source/Target/StopInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/StopInfo.cpp?rev=146806&r1=146805&r2=146806&view=diff
==============================================================================
--- lldb/trunk/source/Target/StopInfo.cpp (original)
+++ lldb/trunk/source/Target/StopInfo.cpp Fri Dec 16 19:35:57 2011
@@ -722,9 +722,10 @@
 {
 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 @@
         }
         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 @@
 }
 
 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 @@
 {
     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();
+}

Modified: lldb/trunk/source/Target/Thread.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Thread.cpp?rev=146806&r1=146805&r2=146806&view=diff
==============================================================================
--- lldb/trunk/source/Target/Thread.cpp (original)
+++ lldb/trunk/source/Target/Thread.cpp Fri Dec 16 19:35:57 2011
@@ -95,7 +95,7 @@
 {
     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 @@
     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)
 {

Modified: lldb/trunk/source/Target/ThreadPlanStepOut.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlanStepOut.cpp?rev=146806&r1=146805&r2=146806&view=diff
==============================================================================
--- lldb/trunk/source/Target/ThreadPlanStepOut.cpp (original)
+++ lldb/trunk/source/Target/ThreadPlanStepOut.cpp Fri Dec 16 19:35:57 2011
@@ -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);
+            }
+        }
+    }
+}

Modified: lldb/trunk/www/formats.html
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/www/formats.html?rev=146806&r1=146805&r2=146806&view=diff
==============================================================================
--- lldb/trunk/www/formats.html (original)
+++ lldb/trunk/www/formats.html Fri Dec 16 19:35:57 2011
@@ -97,6 +97,7 @@
                     <tr valign=top><td><b>thread.name</b></td><td>The name of the thread if the target OS supports naming threads</td></tr>
                     <tr valign=top><td><b>thread.queue</b></td><td>The queue name of the thread if the target OS supports dispatch queues</td></tr>
                     <tr valign=top><td><b>thread.stop-reason</b></td><td>A textual reason each thread stopped</td></tr>
+                    <tr valign=top><td><b>thread.return-value</b></td><td>The return value of the latest step operation (currently only for step-out.)</td></tr>
                     <tr valign=top><td><b>target.arch</b></td><td>The architecture of the current target</td></tr>
                     </table>
                     





More information about the lldb-commits mailing list