Author: jingham
Date: Mon Sep 29 18:17:18 2014
New Revision: 218642

URL: http://llvm.org/viewvc/llvm-project?rev=218642&view=rev
Log:
This checkin is the first step in making the lldb thread stepping mechanism 
more accessible from
the user level.  It adds the ability to invent new stepping modes implemented 
by python classes,
and to view the current thread plan stack and to some extent alter it.

I haven't gotten to documentation or tests yet.  But this should not cause any 
behavior changes
if you don't use it, so its safe to check it in now and work on it 
incrementally.

Added:
    lldb/trunk/include/lldb/API/SBThreadPlan.h
    lldb/trunk/include/lldb/Target/ThreadPlanPython.h
    lldb/trunk/scripts/Python/interface/SBThreadPlan.i
    lldb/trunk/source/API/SBThreadPlan.cpp
    lldb/trunk/source/Target/ThreadPlanPython.cpp
Modified:
    lldb/trunk/include/lldb/API/SBAddress.h
    lldb/trunk/include/lldb/API/SBDefines.h
    lldb/trunk/include/lldb/API/SBEvent.h
    lldb/trunk/include/lldb/API/SBStream.h
    lldb/trunk/include/lldb/API/SBThread.h
    lldb/trunk/include/lldb/Expression/ClangFunction.h
    lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h
    lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h
    lldb/trunk/include/lldb/Target/Thread.h
    lldb/trunk/include/lldb/Target/ThreadPlan.h
    lldb/trunk/include/lldb/Target/ThreadPlanStepRange.h
    lldb/trunk/include/lldb/lldb-private-enumerations.h
    lldb/trunk/lldb.xcodeproj/project.pbxproj
    lldb/trunk/scripts/Python/build-swig-Python.sh
    lldb/trunk/scripts/Python/interface/SBThread.i
    lldb/trunk/scripts/Python/python-swigsafecast.swig
    lldb/trunk/scripts/Python/python-wrapper.swig
    lldb/trunk/scripts/lldb.swig
    lldb/trunk/source/API/SBCommandInterpreter.cpp
    lldb/trunk/source/API/SBEvent.cpp
    lldb/trunk/source/API/SBThread.cpp
    lldb/trunk/source/Commands/CommandObjectThread.cpp
    lldb/trunk/source/Expression/ClangFunction.cpp
    lldb/trunk/source/Expression/ClangUserExpression.cpp
    lldb/trunk/source/Interpreter/ScriptInterpreter.cpp
    lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp
    
lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp
    lldb/trunk/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
    lldb/trunk/source/Target/Thread.cpp
    lldb/trunk/source/Target/ThreadPlanStepInRange.cpp
    lldb/trunk/source/Target/ThreadPlanStepOut.cpp
    lldb/trunk/source/Target/ThreadPlanStepOverRange.cpp
    lldb/trunk/source/Target/ThreadPlanStepRange.cpp

Modified: lldb/trunk/include/lldb/API/SBAddress.h
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBAddress.h?rev=218642&r1=218641&r2=218642&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBAddress.h (original)
+++ lldb/trunk/include/lldb/API/SBAddress.h Mon Sep 29 18:17:18 2014
@@ -117,6 +117,7 @@ protected:
     friend class SBSymbolContext;
     friend class SBTarget;
     friend class SBThread;
+    friend class SBThreadPlan;
     friend class SBValue;
     friend class SBQueueItem;
 

Modified: lldb/trunk/include/lldb/API/SBDefines.h
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBDefines.h?rev=218642&r1=218641&r2=218642&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBDefines.h (original)
+++ lldb/trunk/include/lldb/API/SBDefines.h Mon Sep 29 18:17:18 2014
@@ -71,6 +71,7 @@ class LLDB_API SBSymbolContextList;
 class LLDB_API SBTarget;
 class LLDB_API SBThread;
 class LLDB_API SBThreadCollection;
+class LLDB_API SBThreadPlan;
 class LLDB_API SBType;
 class LLDB_API SBTypeCategory;
 class LLDB_API SBTypeEnumMember;

Modified: lldb/trunk/include/lldb/API/SBEvent.h
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBEvent.h?rev=218642&r1=218641&r2=218642&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBEvent.h (original)
+++ lldb/trunk/include/lldb/API/SBEvent.h Mon Sep 29 18:17:18 2014
@@ -30,6 +30,10 @@ public:
     // Make an event that contains a C string.
     SBEvent (uint32_t event, const char *cstr, uint32_t cstr_len);
 
+    SBEvent (lldb::EventSP &event_sp);
+
+    SBEvent (lldb_private::Event *event_sp);
+
     ~SBEvent();
 
     const SBEvent &
@@ -77,8 +81,6 @@ protected:
     friend class SBThread;
     friend class SBWatchpoint;
 
-    SBEvent (lldb::EventSP &event_sp);
-
     lldb::EventSP &
     GetSP () const;
 

Modified: lldb/trunk/include/lldb/API/SBStream.h
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBStream.h?rev=218642&r1=218641&r2=218642&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBStream.h (original)
+++ lldb/trunk/include/lldb/API/SBStream.h Mon Sep 29 18:17:18 2014
@@ -85,6 +85,7 @@ protected:
     friend class SBSymbolContextList;
     friend class SBTarget;
     friend class SBThread;
+    friend class SBThreadPlan;
     friend class SBType;
     friend class SBTypeEnumMember;
     friend class SBTypeMemberFunction;

Modified: lldb/trunk/include/lldb/API/SBThread.h
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBThread.h?rev=218642&r1=218641&r2=218642&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBThread.h (original)
+++ lldb/trunk/include/lldb/API/SBThread.h Mon Sep 29 18:17:18 2014
@@ -127,6 +127,9 @@ public:
                    uint32_t line);
 
     SBError
+    StepUsingScriptedThreadPlan (const char *script_class_name);
+
+    SBError
     JumpToLine (lldb::SBFileSpec &file_spec, uint32_t line);
 
     void
@@ -216,6 +219,15 @@ public:
     bool
     SafeToCallFunctions ();
 
+#ifndef SWIG
+    lldb_private::Thread *
+    operator->();
+
+    lldb_private::Thread *
+    get();
+
+#endif
+
 protected:
     friend class SBBreakpoint;
     friend class SBBreakpointLocation;

Added: lldb/trunk/include/lldb/API/SBThreadPlan.h
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBThreadPlan.h?rev=218642&view=auto
==============================================================================
--- lldb/trunk/include/lldb/API/SBThreadPlan.h (added)
+++ lldb/trunk/include/lldb/API/SBThreadPlan.h Mon Sep 29 18:17:18 2014
@@ -0,0 +1,129 @@
+//===-- SBThread.h ----------------------------------------------*- C++ 
-*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SBThreadPlan_h_
+#define LLDB_SBThreadPlan_h_
+
+#include "lldb/API/SBDefines.h"
+
+#include <stdio.h>
+
+namespace lldb {
+
+class SBThreadPlan
+{
+
+friend class lldb_private::ThreadPlan;
+
+public:
+    SBThreadPlan ();
+
+    SBThreadPlan (const lldb::SBThreadPlan &threadPlan);
+    
+    SBThreadPlan (const lldb::ThreadPlanSP& lldb_object_sp);
+
+    SBThreadPlan (lldb::SBThread &thread, const char *class_name);
+
+   ~SBThreadPlan ();
+
+    bool
+    IsValid() const;
+
+    void
+    Clear ();
+
+    lldb::StopReason
+    GetStopReason();
+
+    /// Get the number of words associated with the stop reason.
+    /// See also GetStopReasonDataAtIndex().
+    size_t
+    GetStopReasonDataCount();
+
+    
//--------------------------------------------------------------------------
+    /// Get information associated with a stop reason.
+    ///
+    /// Breakpoint stop reasons will have data that consists of pairs of 
+    /// breakpoint IDs followed by the breakpoint location IDs (they always 
come
+    /// in pairs).
+    ///
+    /// Stop Reason              Count Data Type
+    /// ======================== ===== 
=========================================
+    /// eStopReasonNone          0
+    /// eStopReasonTrace         0
+    /// eStopReasonBreakpoint    N     duple: {breakpoint id, location id}
+    /// eStopReasonWatchpoint    1     watchpoint id
+    /// eStopReasonSignal        1     unix signal number
+    /// eStopReasonException     N     exception data
+    /// eStopReasonExec          0
+    /// eStopReasonPlanComplete  0
+    
//--------------------------------------------------------------------------
+    uint64_t
+    GetStopReasonDataAtIndex(uint32_t idx);
+
+    SBThread
+    GetThread () const;
+
+    const lldb::SBThreadPlan &
+    operator = (const lldb::SBThreadPlan &rhs);
+
+    bool
+    GetDescription (lldb::SBStream &description) const;
+
+    void
+    SetPlanComplete (bool success);
+
+    bool
+    IsPlanComplete();
+
+    bool
+    IsValid();
+
+    // This section allows an SBThreadPlan to push another of the common types 
of plans...
+    SBThreadPlan
+    QueueThreadPlanForStepOverRange (SBAddress &start_address,
+                                     lldb::addr_t range_size);
+
+    SBThreadPlan
+    QueueThreadPlanForStepInRange (SBAddress &start_address,
+                                   lldb::addr_t range_size);
+
+    SBThreadPlan
+    QueueThreadPlanForStepOut (uint32_t frame_idx_to_step_to, bool first_insn 
= false);
+
+    SBThreadPlan
+    QueueThreadPlanForRunToAddress (SBAddress address);
+
+#ifndef SWIG
+    lldb_private::ThreadPlan *
+    get();
+#endif
+
+protected:
+    friend class SBBreakpoint;
+    friend class SBBreakpointLocation;
+    friend class SBFrame;
+    friend class SBProcess;
+    friend class SBDebugger;
+    friend class SBValue;
+    friend class lldb_private::QueueImpl;
+    friend class SBQueueItem;
+
+#ifndef SWIG
+    void
+    SetThreadPlan (const lldb::ThreadPlanSP& lldb_object_sp);
+#endif
+
+private:
+    lldb::ThreadPlanSP m_opaque_sp;
+};
+
+} // namespace lldb
+
+#endif  // LLDB_SBThreadPlan_h_

Modified: lldb/trunk/include/lldb/Expression/ClangFunction.h
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangFunction.h?rev=218642&r1=218641&r2=218642&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/ClangFunction.h (original)
+++ lldb/trunk/include/lldb/Expression/ClangFunction.h Mon Sep 29 18:17:18 2014
@@ -285,9 +285,9 @@ public:
     ///     True if the thread plan may simply be discarded if an error occurs.
     ///
     /// @return
-    ///     A ThreadPlan for executing the function.
+    ///     A ThreadPlan shared pointer for executing the function.
     //------------------------------------------------------------------
-    ThreadPlan *
+    lldb::ThreadPlanSP
     GetThreadPlanToCallFunction (ExecutionContext &exe_ctx, 
                                  lldb::addr_t args_addr,
                                  const EvaluateExpressionOptions &options,

Modified: lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h?rev=218642&r1=218641&r2=218642&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h (original)
+++ lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h Mon Sep 29 18:17:18 
2014
@@ -104,6 +104,12 @@ public:
                                                         const char 
*session_dictionary_name,
                                                         const 
lldb::ValueObjectSP& valobj_sp);
 
+    typedef void* (*SWIGPythonCreateScriptedThreadPlan) (const char 
*python_class_name,
+                                                        const char 
*session_dictionary_name,
+                                                        const 
lldb::ThreadPlanSP& thread_plan_sp);
+
+    typedef bool (*SWIGPythonCallThreadPlan) (void *implementor, const char 
*method_name, Event *event_sp, bool &got_error);
+
     typedef void* (*SWIGPythonCreateOSPlugin) (const char *python_class_name,
                                                const char 
*session_dictionary_name,
                                                const lldb::ProcessSP& 
process_sp);
@@ -348,6 +354,39 @@ public:
     }
     
     virtual lldb::ScriptInterpreterObjectSP
+    CreateScriptedThreadPlan (const char *class_name,
+                              lldb::ThreadPlanSP thread_plan_sp)
+    {
+        return lldb::ScriptInterpreterObjectSP();
+    }
+
+    virtual bool
+    ScriptedThreadPlanExplainsStop (lldb::ScriptInterpreterObjectSP 
implementor_sp,
+                                    Event *event,
+                                    bool &script_error)
+    {
+        script_error = true;
+        return true;
+    }
+
+    virtual bool
+    ScriptedThreadPlanShouldStop (lldb::ScriptInterpreterObjectSP 
implementor_sp,
+                                  Event *event,
+                                  bool &script_error)
+    {
+        script_error = true;
+        return true;
+    }
+
+    virtual lldb::StateType
+    ScriptedThreadPlanGetRunState (lldb::ScriptInterpreterObjectSP 
implementor_sp,
+                                   bool &script_error)
+    {
+        script_error = true;
+        return lldb::eStateStepping;
+    }
+
+    virtual lldb::ScriptInterpreterObjectSP
     LoadPluginModule (const FileSpec& file_spec,
                      lldb_private::Error& error)
     {
@@ -573,7 +612,9 @@ public:
                            SWIGPythonScriptKeyword_Thread 
swig_run_script_keyword_thread,
                            SWIGPythonScriptKeyword_Target 
swig_run_script_keyword_target,
                            SWIGPythonScriptKeyword_Frame 
swig_run_script_keyword_frame,
-                           SWIGPython_GetDynamicSetting swig_plugin_get);
+                           SWIGPython_GetDynamicSetting swig_plugin_get,
+                           SWIGPythonCreateScriptedThreadPlan 
swig_thread_plan_script,
+                           SWIGPythonCallThreadPlan swig_call_thread_plan);
 
     virtual void
     ResetOutputFileHandle (FILE *new_fh) { } //By default, do nothing.

Modified: lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h?rev=218642&r1=218641&r2=218642&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h (original)
+++ lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h Mon Sep 29 
18:17:18 2014
@@ -80,6 +80,22 @@ public:
     lldb::ScriptInterpreterObjectSP
     CreateSyntheticScriptedProvider (const char *class_name,
                                      lldb::ValueObjectSP valobj);
+
+    lldb::ScriptInterpreterObjectSP
+    virtual CreateScriptedThreadPlan (const char *class_name,
+                                      lldb::ThreadPlanSP thread_plan);
+
+    virtual bool
+    ScriptedThreadPlanExplainsStop (lldb::ScriptInterpreterObjectSP 
implementor_sp,
+                                    Event *event,
+                                    bool &script_error);
+    virtual bool
+    ScriptedThreadPlanShouldStop (lldb::ScriptInterpreterObjectSP 
implementor_sp,
+                                  Event *event,
+                                  bool &script_error);
+    virtual lldb::StateType
+    ScriptedThreadPlanGetRunState (lldb::ScriptInterpreterObjectSP 
implementor_sp,
+                                   bool &script_error);
     
     virtual lldb::ScriptInterpreterObjectSP
     OSPlugin_CreatePluginObject (const char *class_name,
@@ -275,7 +291,9 @@ public:
                            SWIGPythonScriptKeyword_Thread 
swig_run_script_keyword_thread,
                            SWIGPythonScriptKeyword_Target 
swig_run_script_keyword_target,
                            SWIGPythonScriptKeyword_Frame 
swig_run_script_keyword_frame,
-                           SWIGPython_GetDynamicSetting swig_plugin_get);
+                           SWIGPython_GetDynamicSetting swig_plugin_get,
+                           SWIGPythonCreateScriptedThreadPlan 
swig_thread_plan_script,
+                           SWIGPythonCallThreadPlan swig_call_thread_plan);
 
     const char *
     GetDictionaryName ()

Modified: lldb/trunk/include/lldb/Target/Thread.h
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Thread.h?rev=218642&r1=218641&r2=218642&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Thread.h (original)
+++ lldb/trunk/include/lldb/Target/Thread.h Mon Sep 29 18:17:18 2014
@@ -912,6 +912,11 @@ public:
                                  bool stop_others,
                                  uint32_t frame_idx);
 
+    virtual lldb::ThreadPlanSP
+    QueueThreadPlanForStepScripted (bool abort_other_plans,
+                                    const char *class_name,
+                                    bool stop_other_threads);
+
     //------------------------------------------------------------------
     // Thread Plan accessors:
     //------------------------------------------------------------------
@@ -1041,6 +1046,20 @@ public:
 
     void
     DiscardThreadPlansUpToPlan (ThreadPlan *up_to_plan_ptr);
+
+    //------------------------------------------------------------------
+    /// Discards the plans queued on the plan stack of the current thread up 
to and
+    /// including the plan in that matches \a thread_index counting only
+    /// the non-Private plans.
+    ///
+    /// @param[in] up_to_plan_sp
+    ///   Discard all plans up to and including this user plan given by this 
index.
+    ///
+    /// @return
+    ///    \b true if there was a thread plan with that user index, \b false 
otherwise.
+    //------------------------------------------------------------------
+    bool
+    DiscardUserThreadPlansUpToIndex (uint32_t thread_index);
     
     //------------------------------------------------------------------
     /// Prints the current plan stack.
@@ -1050,7 +1069,10 @@ public:
     ///
     //------------------------------------------------------------------
     void
-    DumpThreadPlans (Stream *s) const;
+    DumpThreadPlans (Stream *s,
+                     lldb::DescriptionLevel desc_level = 
lldb::eDescriptionLevelVerbose,
+                     bool include_internal = true,
+                     bool ignore_boring = false) const;
     
     virtual bool
     CheckpointThreadState (ThreadStateCheckpoint &saved_state);

Modified: lldb/trunk/include/lldb/Target/ThreadPlan.h
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ThreadPlan.h?rev=218642&r1=218641&r2=218642&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/ThreadPlan.h (original)
+++ lldb/trunk/include/lldb/Target/ThreadPlan.h Mon Sep 29 18:17:18 2014
@@ -223,6 +223,7 @@ namespace lldb_private {
 //------------------------------------------------------------------
 
 class ThreadPlan :
+    public std::enable_shared_from_this<ThreadPlan>,
     public UserID
 {
 public:
@@ -241,6 +242,7 @@ public:
         eKindNull,
         eKindBase,
         eKindCallFunction,
+        eKindPython,
         eKindStepInstruction,
         eKindStepOut,
         eKindStepOverBreakpoint,
@@ -687,7 +689,8 @@ protected:
     
     virtual lldb::StateType
     GetPlanRunState ();
-    
+
+    DISALLOW_COPY_AND_ASSIGN(ThreadPlanNull);
 };
 
 

Added: lldb/trunk/include/lldb/Target/ThreadPlanPython.h
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ThreadPlanPython.h?rev=218642&view=auto
==============================================================================
--- lldb/trunk/include/lldb/Target/ThreadPlanPython.h (added)
+++ lldb/trunk/include/lldb/Target/ThreadPlanPython.h Mon Sep 29 18:17:18 2014
@@ -0,0 +1,80 @@
+//===-- ThreadPlanPython.h --------------------------------------------*- C++ 
-*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ThreadPlan_Python_h_
+#define liblldb_ThreadPlan_Python_h_
+
+// C Includes
+// C++ Includes
+#include <string>
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private.h"
+#include "lldb/Core/UserID.h"
+#include "lldb/Host/Mutex.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadPlan.h"
+#include "lldb/Target/ThreadPlanTracer.h"
+#include "lldb/Target/StopInfo.h"
+
+namespace lldb_private {
+
+//------------------------------------------------------------------
+//  ThreadPlanPython:
+//
+//------------------------------------------------------------------
+
+class ThreadPlanPython : public ThreadPlan
+{
+public:
+    ThreadPlanPython (Thread &thread, const char *class_name);
+    virtual ~ThreadPlanPython ();
+    
+    virtual void
+    GetDescription (Stream *s,
+                    lldb::DescriptionLevel level);
+
+    virtual bool
+    ValidatePlan (Stream *error);
+
+    virtual bool
+    ShouldStop (Event *event_ptr);
+
+    virtual bool
+    MischiefManaged ();
+
+    virtual bool
+    WillStop ();
+
+    virtual bool
+    StopOthers ();
+
+    virtual void
+    DidPush ();
+
+protected:
+    virtual bool
+    DoPlanExplainsStop (Event *event_ptr);
+    
+    virtual lldb::StateType
+    GetPlanRunState ();
+
+private:
+    std::string                     m_class_name;
+    lldb::ScriptInterpreterObjectSP m_implementation_sp;
+
+    DISALLOW_COPY_AND_ASSIGN(ThreadPlanPython);
+};
+
+
+} // namespace lldb_private
+
+#endif  // liblldb_ThreadPlan_Python_h_

Modified: lldb/trunk/include/lldb/Target/ThreadPlanStepRange.h
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ThreadPlanStepRange.h?rev=218642&r1=218641&r2=218642&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/ThreadPlanStepRange.h (original)
+++ lldb/trunk/include/lldb/Target/ThreadPlanStepRange.h Mon Sep 29 18:17:18 
2014
@@ -30,7 +30,8 @@ public:
                          Thread &thread,
                          const AddressRange &range,
                          const SymbolContext &addr_context,
-                         lldb::RunMode stop_others);
+                         lldb::RunMode stop_others,
+                         bool given_ranges_only = false);
 
     virtual ~ThreadPlanStepRange ();
 
@@ -83,6 +84,7 @@ protected:
     bool                      m_first_run_event; // We want to broadcast only 
one running event, our first.
     lldb::BreakpointSP        m_next_branch_bp_sp;
     bool                      m_use_fast_step;
+    bool                      m_given_ranges_only;
 
 private:
     std::vector<lldb::DisassemblerSP> m_instruction_ranges;

Modified: lldb/trunk/include/lldb/lldb-private-enumerations.h
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-private-enumerations.h?rev=218642&r1=218641&r2=218642&view=diff
==============================================================================
--- lldb/trunk/include/lldb/lldb-private-enumerations.h (original)
+++ lldb/trunk/include/lldb/lldb-private-enumerations.h Mon Sep 29 18:17:18 2014
@@ -22,7 +22,8 @@ typedef enum StepType
     eStepTypeTraceOver, ///< Single step one instruction, stepping over.
     eStepTypeInto,      ///< Single step into a specified context.
     eStepTypeOver,      ///< Single step over a specified context.
-    eStepTypeOut        ///< Single step out a specified context.
+    eStepTypeOut,       ///< Single step out a specified context.
+    eStepTypeScripted   ///< A step type implemented by the script interpreter.
 } StepType;
 
 //----------------------------------------------------------------------

Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=218642&r1=218641&r2=218642&view=diff
==============================================================================
--- lldb/trunk/lldb.xcodeproj/project.pbxproj (original)
+++ lldb/trunk/lldb.xcodeproj/project.pbxproj Mon Sep 29 18:17:18 2014
@@ -613,6 +613,10 @@
                49DCF6FE170E6B4A0092F75E /* IRMemoryMap.cpp in Sources */ = 
{isa = PBXBuildFile; fileRef = 49DCF6FD170E6B4A0092F75E /* IRMemoryMap.cpp */; 
};
                49DCF702170E70120092F75E /* Materializer.cpp in Sources */ = 
{isa = PBXBuildFile; fileRef = 49DCF700170E70120092F75E /* Materializer.cpp */; 
};
                4C3ADCD61810D88B00357218 /* BreakpointResolverFileRegex.cpp in 
Sources */ = {isa = PBXBuildFile; fileRef = 4CAA56141422D986001FFA01 /* 
BreakpointResolverFileRegex.cpp */; };
+               4C56543119D1EFAA002E9C44 /* ThreadPlanPython.cpp in Sources */ 
= {isa = PBXBuildFile; fileRef = 4C56543019D1EFAA002E9C44 /* 
ThreadPlanPython.cpp */; };
+               4C56543319D1EFB6002E9C44 /* ThreadPlanPython.h in Headers */ = 
{isa = PBXBuildFile; fileRef = 4C56543219D1EFB5002E9C44 /* ThreadPlanPython.h 
*/; };
+               4C56543519D2297A002E9C44 /* SBThreadPlan.h in Headers */ = {isa 
= PBXBuildFile; fileRef = 4C56543419D2297A002E9C44 /* SBThreadPlan.h */; 
settings = {ATTRIBUTES = (Public, ); }; };
+               4C56543719D22B32002E9C44 /* SBThreadPlan.cpp in Sources */ = 
{isa = PBXBuildFile; fileRef = 4C56543619D22B32002E9C44 /* SBThreadPlan.cpp */; 
};
                4C6649A014EEE7F100B0316F /* StreamCallback.h in Headers */ = 
{isa = PBXBuildFile; fileRef = 4C66499F14EEE7F100B0316F /* StreamCallback.h */; 
};
                4C6649A314EEE81000B0316F /* StreamCallback.cpp in Sources */ = 
{isa = PBXBuildFile; fileRef = 4C6649A214EEE81000B0316F /* StreamCallback.cpp 
*/; };
                4C73152219B7D71700F865A4 /* Iterable.h in Headers */ = {isa = 
PBXBuildFile; fileRef = 4C73152119B7D71700F865A4 /* Iterable.h */; };
@@ -1893,6 +1897,11 @@
                4C43DF8611069BFD00E55CBF /* ThreadPlanStepOverRange.h */ = {isa 
= PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name 
= ThreadPlanStepOverRange.h; path = 
include/lldb/Target/ThreadPlanStepOverRange.h; sourceTree = "<group>"; };
                4C43DF8911069C3200E55CBF /* ThreadPlanStepInRange.cpp */ = {isa 
= PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; 
name = ThreadPlanStepInRange.cpp; path = 
source/Target/ThreadPlanStepInRange.cpp; sourceTree = "<group>"; };
                4C43DF8A11069C3200E55CBF /* ThreadPlanStepOverRange.cpp */ = 
{isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = 
sourcecode.cpp.cpp; name = ThreadPlanStepOverRange.cpp; path = 
source/Target/ThreadPlanStepOverRange.cpp; sourceTree = "<group>"; };
+               4C56543019D1EFAA002E9C44 /* ThreadPlanPython.cpp */ = {isa = 
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; 
name = ThreadPlanPython.cpp; path = source/Target/ThreadPlanPython.cpp; 
sourceTree = "<group>"; };
+               4C56543219D1EFB5002E9C44 /* ThreadPlanPython.h */ = {isa = 
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = 
ThreadPlanPython.h; path = include/lldb/Target/ThreadPlanPython.h; sourceTree = 
"<group>"; };
+               4C56543419D2297A002E9C44 /* SBThreadPlan.h */ = {isa = 
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = 
SBThreadPlan.h; path = include/lldb/API/SBThreadPlan.h; sourceTree = "<group>"; 
};
+               4C56543619D22B32002E9C44 /* SBThreadPlan.cpp */ = {isa = 
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; 
name = SBThreadPlan.cpp; path = source/API/SBThreadPlan.cpp; sourceTree = 
"<group>"; };
+               4C56543819D22FD9002E9C44 /* SBThreadPlan.i */ = {isa = 
PBXFileReference; lastKnownFileType = sourcecode.c.c.preprocessed; path = 
SBThreadPlan.i; sourceTree = "<group>"; };
                4C5DBBC611E3FEC60035160F /* CommandObjectCommands.cpp */ = {isa 
= PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; 
name = CommandObjectCommands.cpp; path = 
source/Commands/CommandObjectCommands.cpp; sourceTree = "<group>"; };
                4C5DBBC711E3FEC60035160F /* CommandObjectCommands.h */ = {isa = 
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = 
CommandObjectCommands.h; path = source/Commands/CommandObjectCommands.h; 
sourceTree = "<group>"; };
                4C626533130F1B0A00C889F6 /* StreamTee.h */ = {isa = 
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = 
StreamTee.h; path = include/lldb/Core/StreamTee.h; sourceTree = "<group>"; };
@@ -2669,6 +2678,7 @@
                                2611FF0E142D83060017FEA3 /* 
SBSymbolContextList.i */,
                                2611FF0F142D83060017FEA3 /* SBTarget.i */,
                                2611FF10142D83060017FEA3 /* SBThread.i */,
+                               4C56543819D22FD9002E9C44 /* SBThreadPlan.i */,
                                8CCB018419BA54930009FD44 /* 
SBThreadCollection.i */,
                                2611FF11142D83060017FEA3 /* SBType.i */,
                                9475C18A14E5EA1C001BFC6D /* SBTypeCategory.i */,
@@ -2786,6 +2796,8 @@
                                9A9831091125FC5800A56CB0 /* SBThread.cpp */,
                                8CCB018119BA4E210009FD44 /* 
SBThreadCollection.h */,
                                8CCB017F19BA4DD00009FD44 /* 
SBThreadCollection.cpp */,
+                               4C56543419D2297A002E9C44 /* SBThreadPlan.h */,
+                               4C56543619D22B32002E9C44 /* SBThreadPlan.cpp */,
                                2617447911685869005ADD65 /* SBType.h */,
                                261744771168585B005ADD65 /* SBType.cpp */,
                                9475C18514E5E9C5001BFC6D /* SBTypeCategory.h */,
@@ -3805,6 +3817,8 @@
                                49EC3E98118F90AC00B1265E /* 
ThreadPlanCallFunction.cpp */,
                                4C7CF7E31295E10E00B4FBB5 /* 
ThreadPlanCallUserExpression.h */,
                                4C7CF7E51295E12B00B4FBB5 /* 
ThreadPlanCallUserExpression.cpp */,
+                               4C56543219D1EFB5002E9C44 /* ThreadPlanPython.h 
*/,
+                               4C56543019D1EFAA002E9C44 /* 
ThreadPlanPython.cpp */,
                                4C43DEF9110641F300E55CBF /* 
ThreadPlanShouldStopHere.h */,
                                4C43DEFA110641F300E55CBF /* 
ThreadPlanShouldStopHere.cpp */,
                                260C848010F50F0A00BB2B04 /* 
ThreadPlanStepInstruction.h */,
@@ -4403,6 +4417,7 @@
                                268F9D53123AA15200B91E9B /* 
SBSymbolContextList.h in Headers */,
                                2668022C115FD13D008E1FE4 /* SBTarget.h in 
Headers */,
                                2668022E115FD13D008E1FE4 /* SBThread.h in 
Headers */,
+                               4C56543519D2297A002E9C44 /* SBThreadPlan.h in 
Headers */,
                                263C493A178B50CF0070F12D /* SBModuleSpec.h in 
Headers */,
                                2617447A11685869005ADD65 /* SBType.h in Headers 
*/,
                                9475C18914E5EA08001BFC6D /* SBTypeCategory.h in 
Headers */,
@@ -4495,6 +4510,7 @@
                                26DAED6015D327A200E15819 /* 
OptionValuePathMappings.h in Headers */,
                                26ACEC2815E077AE00E94760 /* Property.h in 
Headers */,
                                26491E3B15E1DB8600CBFFC2 /* OptionValueRegex.h 
in Headers */,
+                               4C56543319D1EFB6002E9C44 /* ThreadPlanPython.h 
in Headers */,
                                2697A39515E404BA003E682C /* OptionValueArch.h 
in Headers */,
                                26474CBF18D0CB2D0073DEBA /* 
RegisterContextMach_i386.h in Headers */,
                                26474CC118D0CB2D0073DEBA /* 
RegisterContextMach_x86_64.h in Headers */,
@@ -4899,6 +4915,7 @@
                                9443B122140C18C40013457C /* SBData.cpp in 
Sources */,
                                4CF52AF8142829390051E832 /* SBFileSpecList.cpp 
in Sources */,
                                23059A101958B319007B8189 /* SBUnixSignals.cpp 
in Sources */,
+                               4C56543719D22B32002E9C44 /* SBThreadPlan.cpp in 
Sources */,
                                8CCB018319BA51BF0009FD44 /* 
SBThreadCollection.cpp in Sources */,
                                26B82840142D020F002DBC64 /* SBSection.cpp in 
Sources */,
                                B2A58724143119D50092BFBA /* SBWatchpoint.cpp in 
Sources */,
@@ -5176,6 +5193,7 @@
                                268900E613353E6F00698AC0 /* Variable.cpp in 
Sources */,
                                268900E713353E6F00698AC0 /* VariableList.cpp in 
Sources */,
                                268900E813353E6F00698AC0 /* ABI.cpp in Sources 
*/,
+                               4C56543119D1EFAA002E9C44 /* 
ThreadPlanPython.cpp in Sources */,
                                26AB92121819D74600E63F3E /* 
DWARFDataExtractor.cpp in Sources */,
                                268900E913353E6F00698AC0 /* 
CPPLanguageRuntime.cpp in Sources */,
                                268900EA13353E6F00698AC0 /* DynamicLoader.cpp 
in Sources */,

Modified: lldb/trunk/scripts/Python/build-swig-Python.sh
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/build-swig-Python.sh?rev=218642&r1=218641&r2=218642&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/build-swig-Python.sh (original)
+++ lldb/trunk/scripts/Python/build-swig-Python.sh Mon Sep 29 18:17:18 2014
@@ -114,6 +114,7 @@ HEADER_FILES="${SRC_ROOT}/include/lldb/l
 " ${SRC_ROOT}/include/lldb/API/SBTarget.h"\
 " ${SRC_ROOT}/include/lldb/API/SBThread.h"\
 " ${SRC_ROOT}/include/lldb/API/SBThreadCollection.h"\
+" ${SRC_ROOT}/include/lldb/API/SBThreadPlan.h"\
 " ${SRC_ROOT}/include/lldb/API/SBType.h"\
 " ${SRC_ROOT}/include/lldb/API/SBTypeCategory.h"\
 " ${SRC_ROOT}/include/lldb/API/SBTypeFilter.h"\
@@ -163,6 +164,7 @@ INTERFACE_FILES="${SRC_ROOT}/scripts/Pyt
 " ${SRC_ROOT}/scripts/Python/interface/SBTarget.i"\
 " ${SRC_ROOT}/scripts/Python/interface/SBThread.i"\
 " ${SRC_ROOT}/scripts/Python/interface/SBThreadCollection.i"\
+" ${SRC_ROOT}/scripts/Python/interface/SBThreadPlan.i"\
 " ${SRC_ROOT}/scripts/Python/interface/SBType.i"\
 " ${SRC_ROOT}/scripts/Python/interface/SBTypeCategory.i"\
 " ${SRC_ROOT}/scripts/Python/interface/SBTypeFilter.i"\

Modified: lldb/trunk/scripts/Python/interface/SBThread.i
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/interface/SBThread.i?rev=218642&r1=218641&r2=218642&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/interface/SBThread.i (original)
+++ lldb/trunk/scripts/Python/interface/SBThread.i Mon Sep 29 18:17:18 2014
@@ -213,6 +213,9 @@ public:
                    uint32_t line);
 
     SBError
+    StepUsingScriptedThreadPlan (const char *script_class_name);
+
+    SBError
     JumpToLine (lldb::SBFileSpec &file_spec, uint32_t line);
 
     void

Added: lldb/trunk/scripts/Python/interface/SBThreadPlan.i
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/interface/SBThreadPlan.i?rev=218642&view=auto
==============================================================================
--- lldb/trunk/scripts/Python/interface/SBThreadPlan.i (added)
+++ lldb/trunk/scripts/Python/interface/SBThreadPlan.i Mon Sep 29 18:17:18 2014
@@ -0,0 +1,123 @@
+//===-- SBThread.h ----------------------------------------------*- C++ 
-*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SBThreadPlan_h_
+#define LLDB_SBThreadPlan_h_
+
+#include "lldb/API/SBDefines.h"
+
+#include <stdio.h>
+
+namespace lldb {
+
+%feature("docstring",
+"Represents a plan for the execution control of a given thread.
+
+See also SBThread and SBFrame."
+) SBThread;
+
+class SBThreadPlan
+{
+
+friend class lldb_private::ThreadPlan;
+
+public:
+    SBThreadPlan ();
+
+    SBThreadPlan (const lldb::SBThreadPlan &threadPlan);
+    
+    SBThreadPlan (const lldb::ThreadPlanSP& lldb_object_sp);
+
+    SBThreadPlan (lldb::SBThread &thread, const char *class_name);
+
+   ~SBThreadPlan ();
+
+    bool
+    IsValid() const;
+
+    void
+    Clear ();
+
+    lldb::StopReason
+    GetStopReason();
+
+    /// Get the number of words associated with the stop reason.
+    /// See also GetStopReasonDataAtIndex().
+    size_t
+    GetStopReasonDataCount();
+
+    
//--------------------------------------------------------------------------
+    /// Get information associated with a stop reason.
+    ///
+    /// Breakpoint stop reasons will have data that consists of pairs of 
+    /// breakpoint IDs followed by the breakpoint location IDs (they always 
come
+    /// in pairs).
+    ///
+    /// Stop Reason              Count Data Type
+    /// ======================== ===== 
=========================================
+    /// eStopReasonNone          0
+    /// eStopReasonTrace         0
+    /// eStopReasonBreakpoint    N     duple: {breakpoint id, location id}
+    /// eStopReasonWatchpoint    1     watchpoint id
+    /// eStopReasonSignal        1     unix signal number
+    /// eStopReasonException     N     exception data
+    /// eStopReasonExec          0
+    /// eStopReasonPlanComplete  0
+    
//--------------------------------------------------------------------------
+    uint64_t
+    GetStopReasonDataAtIndex(uint32_t idx);
+
+    SBThread
+    GetThread () const;
+
+    bool
+    GetDescription (lldb::SBStream &description) const;
+
+    void
+    SetPlanComplete (bool success);
+
+    bool
+    IsPlanComplete();
+
+    bool
+    IsValid();
+
+    // This section allows an SBThreadPlan to push another of the common types 
of plans...
+    SBThreadPlan
+    QueueThreadPlanForStepOverRange (SBAddress &start_address,
+                                     lldb::addr_t range_size);
+
+    SBThreadPlan
+    QueueThreadPlanForStepInRange (SBAddress &start_address,
+                                   lldb::addr_t range_size);
+
+    SBThreadPlan
+    QueueThreadPlanForStepOut (uint32_t frame_idx_to_step_to, bool first_insn 
= false);
+    
+    SBThreadPlan
+    QueueThreadPlanForRunToAddress (SBAddress address);
+
+
+protected:
+    friend class SBBreakpoint;
+    friend class SBBreakpointLocation;
+    friend class SBFrame;
+    friend class SBProcess;
+    friend class SBDebugger;
+    friend class SBValue;
+    friend class lldb_private::QueueImpl;
+    friend class SBQueueItem;
+
+private:
+    lldb::ThreadPlanSP m_opaque_sp;
+};
+
+} // namespace lldb
+
+#endif  // LLDB_SBThreadPlan_h_

Modified: lldb/trunk/scripts/Python/python-swigsafecast.swig
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/python-swigsafecast.swig?rev=218642&r1=218641&r2=218642&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/python-swigsafecast.swig (original)
+++ lldb/trunk/scripts/Python/python-swigsafecast.swig Mon Sep 29 18:17:18 2014
@@ -45,6 +45,13 @@ SBTypeToSWIGWrapper (unsigned int* c_int
 
 template <>
 PyObject*
+SBTypeToSWIGWrapper (lldb::SBEvent* event_sb)
+{
+    return SWIG_NewPointerObj((void *) event_sb, SWIGTYPE_p_lldb__SBEvent, 0);
+}
+
+template <>
+PyObject*
 SBTypeToSWIGWrapper (lldb::SBProcess* process_sb)
 {
     return SWIG_NewPointerObj((void *) process_sb, SWIGTYPE_p_lldb__SBProcess, 
0);
@@ -58,6 +65,13 @@ SBTypeToSWIGWrapper (lldb::SBThread* thr
 }
 
 template <>
+PyObject*
+SBTypeToSWIGWrapper (lldb::SBThreadPlan* thread_plan_sb)
+{
+    return SWIG_NewPointerObj((void *) thread_plan_sb, 
SWIGTYPE_p_lldb__SBThreadPlan, 0);
+}
+
+template <>
 PyObject*
 SBTypeToSWIGWrapper (lldb::SBTarget* target_sb)
 {

Modified: lldb/trunk/scripts/Python/python-wrapper.swig
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/python-wrapper.swig?rev=218642&r1=218641&r2=218642&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/python-wrapper.swig (original)
+++ lldb/trunk/scripts/Python/python-wrapper.swig Mon Sep 29 18:17:18 2014
@@ -419,6 +419,118 @@ LLDBSwigPythonCreateSyntheticProvider
         Py_RETURN_NONE;
 }
 
+SWIGEXPORT void*
+LLDBSwigPythonCreateScriptedThreadPlan
+(
+    const char *python_class_name,
+    const char *session_dictionary_name,
+    const lldb::ThreadPlanSP& thread_plan_sp
+)
+{
+    PyObject* retval = NULL;
+
+    if (python_class_name == NULL || python_class_name[0] == '\0' || 
!session_dictionary_name)
+        Py_RETURN_NONE;
+
+    // I do not want the SBThreadPlan to be deallocated when going out of 
scope because python
+    // has ownership of it and will manage memory for this object by itself
+    lldb::SBThreadPlan *tp_value = new lldb::SBThreadPlan(thread_plan_sp);
+
+    PyObject *ThreadPlan_PyObj = SBTypeToSWIGWrapper(tp_value);
+
+    if (ThreadPlan_PyObj == NULL)
+        Py_RETURN_NONE;
+    
+    {
+        PyErr_Cleaner py_err_cleaner(true);
+        
+        PyCallable pfunc = PyCallable::FindWithFunctionName(python_class_name, 
session_dictionary_name);
+        
+        if (!pfunc)
+            return retval;
+        
+        Py_INCREF(ThreadPlan_PyObj);
+        
+        PyObject* session_dict = NULL;
+        session_dict = FindSessionDictionary(session_dictionary_name);
+        retval = pfunc(tp_value, session_dict);
+
+        // FIXME: At this point we should check that the class we found 
supports all the methods
+        // that we need.
+        
+        Py_XINCREF (session_dict);
+        
+        Py_XINCREF(retval);
+    }
+
+    if (retval)
+        return retval;
+    else
+        Py_RETURN_NONE;
+}
+
+SWIGEXPORT bool
+LLDBSWIGPythonCallThreadPlan
+(
+    void *implementor,
+    const char *method_name,
+    lldb_private::Event *event,
+    bool &got_error
+)
+{
+    bool ret_val = false;
+    got_error = false;
+
+
+    PyErr_Cleaner py_err_cleaner(false);
+    
+    PyCallable pfunc = PyCallable::FindWithMemberFunction((PyObject *) 
implementor, method_name);
+    
+    if (!pfunc)
+    {
+        return ret_val;
+    }
+
+    PyObject* py_return = Py_None;
+
+    if (event != NULL)
+    {
+        lldb::SBEvent sb_event(event);
+
+        PyObject *py_obj_event = SBTypeToSWIGWrapper(sb_event);
+
+        py_return = pfunc(py_obj_event);
+    }
+    else
+    {
+        py_return = pfunc();
+    }
+
+    if (PyErr_Occurred())
+    {
+        got_error = true;
+        printf ("Return value was neither false nor true for call to %s.\n", 
method_name);
+        PyErr_Print();
+    }
+    else
+    {
+        if (py_return == Py_True)
+            ret_val = true;
+        else if (py_return == Py_False)
+            ret_val = false;
+        else
+        {
+            // Somebody returned the wrong thing...
+            got_error = true;
+            printf ("Wrong return value type for call to %s.\n", method_name);
+        }
+    }
+    
+    Py_XDECREF(py_return);
+
+    return ret_val;
+}
+
 // wrapper that calls an optional instance member of an object taking no 
arguments
 static PyObject*
 LLDBSwigPython_CallOptionalMember

Modified: lldb/trunk/scripts/lldb.swig
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/lldb.swig?rev=218642&r1=218641&r2=218642&view=diff
==============================================================================
--- lldb/trunk/scripts/lldb.swig (original)
+++ lldb/trunk/scripts/lldb.swig Mon Sep 29 18:17:18 2014
@@ -92,6 +92,7 @@ import os
 #include "lldb/API/SBTarget.h"
 #include "lldb/API/SBThread.h"
 #include "lldb/API/SBThreadCollection.h"
+#include "lldb/API/SBThreadPlan.h"
 #include "lldb/API/SBType.h"
 #include "lldb/API/SBTypeCategory.h"
 #include "lldb/API/SBTypeEnumMember.h"
@@ -164,6 +165,7 @@ import os
 %include "./Python/interface/SBTarget.i"
 %include "./Python/interface/SBThread.i"
 %include "./Python/interface/SBThreadCollection.i"
+%include "./Python/interface/SBThreadPlan.i"
 %include "./Python/interface/SBType.i"
 %include "./Python/interface/SBTypeCategory.i"
 %include "./Python/interface/SBTypeEnumMember.i"

Modified: lldb/trunk/source/API/SBCommandInterpreter.cpp
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBCommandInterpreter.cpp?rev=218642&r1=218641&r2=218642&view=diff
==============================================================================
--- lldb/trunk/source/API/SBCommandInterpreter.cpp (original)
+++ lldb/trunk/source/API/SBCommandInterpreter.cpp Mon Sep 29 18:17:18 2014
@@ -442,6 +442,17 @@ LLDBSwigPythonCreateSyntheticProvider (c
                                        const lldb::ValueObjectSP& valobj_sp);
 
 
+extern "C" void*
+LLDBSwigPythonCreateScriptedThreadPlan (const char *python_class_name,
+                                        const char *session_dictionary_name,
+                                        const lldb::ThreadPlanSP& 
thread_plan_sp);
+
+extern "C" bool
+LLDBSWIGPythonCallThreadPlan (void *implementor,
+                              const char *method_name,
+                              Event *event_sp,
+                              bool &got_error);
+
 extern "C" uint32_t
 LLDBSwigPython_CalculateNumChildren (void *implementor);
 
@@ -539,7 +550,9 @@ SBCommandInterpreter::InitializeSWIG ()
                                                   
LLDBSWIGPythonRunScriptKeywordThread,
                                                   
LLDBSWIGPythonRunScriptKeywordTarget,
                                                   
LLDBSWIGPythonRunScriptKeywordFrame,
-                                                  
LLDBSWIGPython_GetDynamicSetting);
+                                                  
LLDBSWIGPython_GetDynamicSetting,
+                                                  
LLDBSwigPythonCreateScriptedThreadPlan,
+                                                  
LLDBSWIGPythonCallThreadPlan);
 #endif
     }
 }

Modified: lldb/trunk/source/API/SBEvent.cpp
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBEvent.cpp?rev=218642&r1=218641&r2=218642&view=diff
==============================================================================
--- lldb/trunk/source/API/SBEvent.cpp (original)
+++ lldb/trunk/source/API/SBEvent.cpp Mon Sep 29 18:17:18 2014
@@ -43,6 +43,12 @@ SBEvent::SBEvent (EventSP &event_sp) :
 {
 }
 
+SBEvent::SBEvent (Event *event_ptr) :
+    m_event_sp (),
+    m_opaque_ptr (event_ptr)
+{
+}
+
 SBEvent::SBEvent (const SBEvent &rhs) :
     m_event_sp (rhs.m_event_sp),
     m_opaque_ptr (rhs.m_opaque_ptr)

Modified: lldb/trunk/source/API/SBThread.cpp
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBThread.cpp?rev=218642&r1=218641&r2=218642&view=diff
==============================================================================
--- lldb/trunk/source/API/SBThread.cpp (original)
+++ lldb/trunk/source/API/SBThread.cpp Mon Sep 29 18:17:18 2014
@@ -41,6 +41,7 @@
 #include "lldb/API/SBEvent.h"
 #include "lldb/API/SBFrame.h"
 #include "lldb/API/SBProcess.h"
+#include "lldb/API/SBThreadPlan.h"
 #include "lldb/API/SBValue.h"
 
 using namespace lldb;
@@ -918,7 +919,9 @@ SBThread::RunToAddress (lldb::addr_t add
 
         Thread *thread = exe_ctx.GetThreadPtr();
 
-        ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress 
(abort_other_plans, target_addr, stop_other_threads));
+        ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress 
(abort_other_plans,
+                                                                         
target_addr,
+                                                                         
stop_other_threads));
 
         // This returns an error, we should use it!
         ResumeNewPlan (exe_ctx, new_plan_sp.get());
@@ -1073,6 +1076,46 @@ SBThread::StepOverUntil (lldb::SBFrame &
 }
 
 SBError
+SBThread::StepUsingScriptedThreadPlan (const char *script_class_name)
+{
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+    SBError sb_error;
+
+    Mutex::Locker api_locker;
+    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
+
+    if (log)
+    {
+        log->Printf ("SBThread(%p)::StepUsingScriptedThreadPlan: class name: 
%s",
+                     static_cast<void*>(exe_ctx.GetThreadPtr()),
+                     script_class_name);
+    }
+
+
+    if (!exe_ctx.HasThreadScope())
+    {
+        sb_error.SetErrorString("this SBThread object is invalid");
+        return sb_error;
+    }
+
+    Thread *thread = exe_ctx.GetThreadPtr();
+    ThreadPlanSP thread_plan_sp = 
thread->QueueThreadPlanForStepScripted(false, script_class_name, false);
+
+    if (thread_plan_sp)
+        sb_error = ResumeNewPlan(exe_ctx, thread_plan_sp.get());
+    else
+    {
+        sb_error.SetErrorStringWithFormat("Error queuing thread plan for 
class: %s.", script_class_name);
+        if (log)
+        log->Printf ("SBThread(%p)::StepUsingScriptedThreadPlan: Error queuing 
thread plan for class: %s",
+                     static_cast<void*>(exe_ctx.GetThreadPtr()),
+                     script_class_name);
+    }
+
+    return sb_error;
+}
+
+SBError
 SBThread::JumpToLine (lldb::SBFileSpec &file_spec, uint32_t line)
 {
     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
@@ -1473,7 +1516,8 @@ SBThread::GetExtendedBacktraceThread (co
                                 const char *queue_name = 
new_thread_sp->GetQueueName();
                                 if (queue_name == NULL)
                                     queue_name = "";
-                                log->Printf 
("SBThread(%p)::GetExtendedBacktraceThread() => new extended Thread created 
(%p) with queue_id 0x%" PRIx64 " queue name '%s'",
+                                log->Printf 
("SBThread(%p)::GetExtendedBacktraceThread() => new extended Thread "
+                                             "created (%p) with queue_id 0x%" 
PRIx64 " queue name '%s'",
                                              
static_cast<void*>(exe_ctx.GetThreadPtr()),
                                              
static_cast<void*>(new_thread_sp.get()),
                                              new_thread_sp->GetQueueID(),
@@ -1515,3 +1559,24 @@ SBThread::SafeToCallFunctions ()
         return thread_sp->SafeToCallFunctions();
     return true;
 }
+
+lldb_private::Thread *
+SBThread::operator->()
+{
+    ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
+    if (thread_sp)
+        return thread_sp.get();
+    else
+        return NULL;
+}
+
+lldb_private::Thread *
+SBThread::get()
+{
+    ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
+    if (thread_sp)
+        return thread_sp.get();
+    else
+        return NULL;
+}
+

Added: lldb/trunk/source/API/SBThreadPlan.cpp
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBThreadPlan.cpp?rev=218642&view=auto
==============================================================================
--- lldb/trunk/source/API/SBThreadPlan.cpp (added)
+++ lldb/trunk/source/API/SBThreadPlan.cpp Mon Sep 29 18:17:18 2014
@@ -0,0 +1,285 @@
+//===-- SBThread.cpp --------------------------------------------*- C++ 
-*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/lldb-python.h"
+
+#include "lldb/API/SBThread.h"
+
+#include "lldb/API/SBSymbolContext.h"
+#include "lldb/API/SBFileSpec.h"
+#include "lldb/API/SBStream.h"
+#include "lldb/Breakpoint/BreakpointLocation.h"
+#include "lldb/Core/Debugger.h"
+#include "lldb/Core/State.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Core/StreamFile.h"
+#include "lldb/Core/StructuredData.h"
+#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Target/SystemRuntime.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadPlan.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Queue.h"
+#include "lldb/Symbol/SymbolContext.h"
+#include "lldb/Symbol/CompileUnit.h"
+#include "lldb/Target/StopInfo.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/ThreadPlan.h"
+#include "lldb/Target/ThreadPlanPython.h"
+#include "lldb/Target/ThreadPlanStepInstruction.h"
+#include "lldb/Target/ThreadPlanStepOut.h"
+#include "lldb/Target/ThreadPlanStepRange.h"
+#include "lldb/Target/ThreadPlanStepInRange.h"
+
+
+#include "lldb/API/SBAddress.h"
+#include "lldb/API/SBDebugger.h"
+#include "lldb/API/SBEvent.h"
+#include "lldb/API/SBFrame.h"
+#include "lldb/API/SBProcess.h"
+#include "lldb/API/SBThreadPlan.h"
+#include "lldb/API/SBValue.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+//----------------------------------------------------------------------
+// Constructors
+//----------------------------------------------------------------------
+SBThreadPlan::SBThreadPlan ()
+{
+}
+
+SBThreadPlan::SBThreadPlan (const ThreadPlanSP& lldb_object_sp) :
+    m_opaque_sp (lldb_object_sp)
+{
+}
+
+SBThreadPlan::SBThreadPlan (const SBThreadPlan &rhs) :
+    m_opaque_sp (rhs.m_opaque_sp)
+{
+    
+}
+
+SBThreadPlan::SBThreadPlan (lldb::SBThread &sb_thread, const char *class_name)
+{
+    Thread *thread = sb_thread.get();
+    if (thread)
+        m_opaque_sp.reset(new ThreadPlanPython(*thread, class_name));
+}
+
+//----------------------------------------------------------------------
+// Assignment operator
+//----------------------------------------------------------------------
+
+const lldb::SBThreadPlan &
+SBThreadPlan::operator = (const SBThreadPlan &rhs)
+{
+    if (this != &rhs)
+        m_opaque_sp = rhs.m_opaque_sp;
+    return *this;
+}
+//----------------------------------------------------------------------
+// Destructor
+//----------------------------------------------------------------------
+SBThreadPlan::~SBThreadPlan()
+{
+}
+
+lldb_private::ThreadPlan *
+SBThreadPlan::get()
+{
+    return m_opaque_sp.get();
+}
+
+bool
+SBThreadPlan::IsValid() const
+{
+    return m_opaque_sp.get() != NULL;
+}
+
+void
+SBThreadPlan::Clear ()
+{
+    m_opaque_sp.reset();
+}
+
+lldb::StopReason
+SBThreadPlan::GetStopReason()
+{
+    return eStopReasonNone;
+}
+
+size_t
+SBThreadPlan::GetStopReasonDataCount()
+{
+    return 0;
+}
+
+uint64_t
+SBThreadPlan::GetStopReasonDataAtIndex(uint32_t idx)
+{
+    return 0;
+}
+
+SBThread
+SBThreadPlan::GetThread () const
+{
+    if (m_opaque_sp)
+    {
+        return SBThread(m_opaque_sp->GetThread().shared_from_this());
+    }
+    else
+        return SBThread();
+}
+
+bool
+SBThreadPlan::GetDescription (lldb::SBStream &description) const
+{
+    if (m_opaque_sp)
+    {
+        m_opaque_sp->GetDescription(description.get(), eDescriptionLevelFull);
+    }
+    else
+    {
+        description.Printf("Empty SBThreadPlan");
+    }
+    return true;
+}
+
+void
+SBThreadPlan::SetThreadPlan (const ThreadPlanSP& lldb_object_sp)
+{
+    m_opaque_sp = lldb_object_sp;
+}
+
+void
+SBThreadPlan::SetPlanComplete (bool success)
+{
+    if (m_opaque_sp)
+        m_opaque_sp->SetPlanComplete (success);
+}
+
+bool
+SBThreadPlan::IsPlanComplete()
+{
+    if (m_opaque_sp)
+        return m_opaque_sp->IsPlanComplete();
+    else
+        return true;
+}
+
+bool
+SBThreadPlan::IsValid()
+{
+    if (m_opaque_sp)
+        return m_opaque_sp->ValidatePlan(nullptr);
+    else
+        return false;
+}
+
+    // This section allows an SBThreadPlan to push another of the common types 
of plans...
+    //
+    // FIXME, you should only be able to queue thread plans from inside the 
methods of a
+    // Scripted Thread Plan.  Need a way to enforce that.
+
+SBThreadPlan
+SBThreadPlan::QueueThreadPlanForStepOverRange (SBAddress &sb_start_address,
+                                               lldb::addr_t size)
+{
+    if (m_opaque_sp)
+    {
+        Address *start_address = sb_start_address.get();
+        if (!start_address)
+        {
+            return SBThreadPlan();
+        }
+
+        AddressRange range (*start_address, size);
+        SymbolContext sc;
+        start_address->CalculateSymbolContext(&sc);
+        return SBThreadPlan 
(m_opaque_sp->GetThread().QueueThreadPlanForStepOverRange (false,
+                                                                               
       range,
+                                                                               
       sc,
+                                                                               
       eAllThreads));
+    }
+    else
+    {
+        return SBThreadPlan();
+    }
+}
+
+SBThreadPlan
+SBThreadPlan::QueueThreadPlanForStepInRange (SBAddress &sb_start_address,
+                                               lldb::addr_t size)
+{
+    if (m_opaque_sp)
+    {
+        Address *start_address = sb_start_address.get();
+        if (!start_address)
+        {
+            return SBThreadPlan();
+        }
+
+        AddressRange range (*start_address, size);
+        SymbolContext sc;
+        start_address->CalculateSymbolContext(&sc);
+        return SBThreadPlan 
(m_opaque_sp->GetThread().QueueThreadPlanForStepInRange (false,
+                                                                               
       range,
+                                                                               
       sc,
+                                                                               
       NULL,
+                                                                               
       eAllThreads));
+    }
+    else
+    {
+        return SBThreadPlan();
+    }
+}
+
+SBThreadPlan
+SBThreadPlan::QueueThreadPlanForStepOut (uint32_t frame_idx_to_step_to, bool 
first_insn)
+{
+    if (m_opaque_sp)
+    {
+        SymbolContext sc;
+        sc = 
m_opaque_sp->GetThread().GetStackFrameAtIndex(0)->GetSymbolContext(lldb::eSymbolContextEverything);
+        return SBThreadPlan 
(m_opaque_sp->GetThread().QueueThreadPlanForStepOut (false,
+                                                                               
  &sc,
+                                                                               
  first_insn,
+                                                                               
  false,
+                                                                               
  eVoteYes,
+                                                                               
  eVoteNoOpinion,
+                                                                               
  frame_idx_to_step_to));
+    }
+    else
+    {
+        return SBThreadPlan();
+    }
+}
+
+SBThreadPlan
+SBThreadPlan::QueueThreadPlanForRunToAddress (SBAddress sb_address)
+{
+    if (m_opaque_sp)
+    {
+        Address *address = sb_address.get();
+        if (!address)
+            return SBThreadPlan();
+
+        return SBThreadPlan 
(m_opaque_sp->GetThread().QueueThreadPlanForRunToAddress (false,
+                                                                               
       *address,
+                                                                               
       false));
+    }
+    else
+    {
+        return SBThreadPlan();
+    }
+}
+
+

Modified: lldb/trunk/source/Commands/CommandObjectThread.cpp
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectThread.cpp?rev=218642&r1=218641&r2=218642&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectThread.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectThread.cpp Mon Sep 29 18:17:18 2014
@@ -46,7 +46,108 @@ using namespace lldb_private;
 // CommandObjectThreadBacktrace
 //-------------------------------------------------------------------------
 
-class CommandObjectThreadBacktrace : public CommandObjectParsed
+class CommandObjectIterateOverThreads : public CommandObjectParsed
+{
+public:
+    CommandObjectIterateOverThreads (CommandInterpreter &interpreter,
+                         const char *name,
+                         const char *help,
+                         const char *syntax,
+                         uint32_t flags) :
+        CommandObjectParsed (interpreter, name, help, syntax, flags)
+    {
+    }
+
+    virtual ~CommandObjectIterateOverThreads() {}
+    virtual bool
+    DoExecute (Args& command, CommandReturnObject &result)
+    {        
+        result.SetStatus (m_success_return);
+
+        if (command.GetArgumentCount() == 0)
+        {
+            Thread *thread = m_exe_ctx.GetThreadPtr();
+            if (!HandleOneThread (*thread, result))
+                return false;
+        }
+        else if (command.GetArgumentCount() == 1 && ::strcmp 
(command.GetArgumentAtIndex(0), "all") == 0)
+        {
+            Process *process = m_exe_ctx.GetProcessPtr();
+            uint32_t idx = 0;
+            for (ThreadSP thread_sp : process->Threads())
+            {
+                if (idx != 0 && m_add_return)
+                    result.AppendMessage("");
+
+                if (!HandleOneThread(*(thread_sp.get()), result))
+                    return false;
+                ++idx;
+            }
+        }
+        else
+        {
+            const size_t num_args = command.GetArgumentCount();
+            Process *process = m_exe_ctx.GetProcessPtr();
+            Mutex::Locker locker (process->GetThreadList().GetMutex());
+            std::vector<ThreadSP> thread_sps;
+
+            for (size_t i = 0; i < num_args; i++)
+            {
+                bool success;
+                
+                uint32_t thread_idx = 
Args::StringToUInt32(command.GetArgumentAtIndex(i), 0, 0, &success);
+                if (!success)
+                {
+                    result.AppendErrorWithFormat ("invalid thread 
specification: \"%s\"\n", command.GetArgumentAtIndex(i));
+                    result.SetStatus (eReturnStatusFailed);
+                    return false;
+                }
+                
+                
thread_sps.push_back(process->GetThreadList().FindThreadByIndexID(thread_idx));
+                
+                if (!thread_sps[i])
+                {
+                    result.AppendErrorWithFormat ("no thread with index: 
\"%s\"\n", command.GetArgumentAtIndex(i));
+                    result.SetStatus (eReturnStatusFailed);
+                    return false;
+                }
+                
+            }
+            
+            for (uint32_t i = 0; i < num_args; i++)
+            {
+                if (!HandleOneThread (*(thread_sps[i].get()), result))
+                    return false;
+
+                if (i < num_args - 1 && m_add_return)
+                    result.AppendMessage("");
+            }
+        }
+        return result.Succeeded();
+    }
+
+protected:
+
+    // Override this to do whatever you need to do for one thread.
+    //
+    // If you return false, the iteration will stop, otherwise it will proceed.
+    // The result is set to m_success_return (defaults to 
eReturnStatusSuccessFinishResult) before the iteration,
+    // so you only need to set the return status in HandleOneThread if you 
want to indicate an error.
+    // If m_add_return is true, a blank line will be inserted between each of 
the listings (except the last one.)
+
+    virtual bool
+    HandleOneThread (Thread &thread, CommandReturnObject &result) = 0;
+
+    ReturnStatus m_success_return = eReturnStatusSuccessFinishResult;
+    bool m_add_return = true;
+
+};
+
+//-------------------------------------------------------------------------
+// CommandObjectThreadBacktrace
+//-------------------------------------------------------------------------
+
+class CommandObjectThreadBacktrace : public CommandObjectIterateOverThreads
 {
 public:
 
@@ -134,7 +235,7 @@ public:
     };
 
     CommandObjectThreadBacktrace (CommandInterpreter &interpreter) :
-        CommandObjectParsed (interpreter,
+        CommandObjectIterateOverThreads (interpreter,
                              "thread backtrace",
                              "Show the stack for one or more threads.  If no 
threads are specified, show the currently selected thread.  Use the 
thread-index \"all\" to see all threads.",
                              NULL,
@@ -145,18 +246,6 @@ public:
                              eFlagProcessMustBePaused   ),
         m_options(interpreter)
     {
-        CommandArgumentEntry arg;
-        CommandArgumentData thread_idx_arg;
-        
-        // Define the first (and only) variant of this arg.
-        thread_idx_arg.arg_type = eArgTypeThreadIndex;
-        thread_idx_arg.arg_repetition = eArgRepeatStar;
-        
-        // There is only one variant this argument could be; put it into the 
argument entry.
-        arg.push_back (thread_idx_arg);
-        
-        // Push the data for the first argument into the m_arguments vector.
-        m_arguments.push_back (arg);
     }
 
     ~CommandObjectThreadBacktrace()
@@ -197,106 +286,28 @@ protected:
     }
 
     virtual bool
-    DoExecute (Args& command, CommandReturnObject &result)
-    {        
-        result.SetStatus (eReturnStatusSuccessFinishResult);
+    HandleOneThread (Thread &thread, CommandReturnObject &result)
+    {
         Stream &strm = result.GetOutputStream();
 
         // Don't show source context when doing backtraces.
         const uint32_t num_frames_with_source = 0;
-        if (command.GetArgumentCount() == 0)
-        {
-            Thread *thread = m_exe_ctx.GetThreadPtr();
-            // Thread::GetStatus() returns the number of frames shown.
-            if (thread->GetStatus (strm,
+
+        if (!thread.GetStatus (strm,
                                    m_options.m_start,
                                    m_options.m_count,
                                    num_frames_with_source))
-            {
-                result.SetStatus (eReturnStatusSuccessFinishResult);
-                if (m_options.m_extended_backtrace)
-                {
-                    DoExtendedBacktrace (thread, result);
-                }
-            }
-        }
-        else if (command.GetArgumentCount() == 1 && ::strcmp 
(command.GetArgumentAtIndex(0), "all") == 0)
         {
-            Process *process = m_exe_ctx.GetProcessPtr();
-            uint32_t idx = 0;
-            for (ThreadSP thread_sp : process->Threads())
-            {
-                if (idx != 0)
-                    result.AppendMessage("");
-
-                if (!thread_sp->GetStatus (strm,
-                                           m_options.m_start,
-                                           m_options.m_count,
-                                           num_frames_with_source))
-                {
-                    result.AppendErrorWithFormat ("error displaying backtrace 
for thread: \"0x%4.4x\"\n", idx);
-                    result.SetStatus (eReturnStatusFailed);
-                    return false;
-                }
-                if (m_options.m_extended_backtrace)
-                {
-                    DoExtendedBacktrace (thread_sp.get(), result);
-                }
-                
-                ++idx;
-            }
+            result.AppendErrorWithFormat ("error displaying backtrace for 
thread: \"0x%4.4x\"\n", thread.GetIndexID());
+            result.SetStatus (eReturnStatusFailed);
+            return false;
         }
-        else
+        if (m_options.m_extended_backtrace)
         {
-            const size_t num_args = command.GetArgumentCount();
-            Process *process = m_exe_ctx.GetProcessPtr();
-            Mutex::Locker locker (process->GetThreadList().GetMutex());
-            std::vector<ThreadSP> thread_sps;
-
-            for (size_t i = 0; i < num_args; i++)
-            {
-                bool success;
-                
-                uint32_t thread_idx = 
Args::StringToUInt32(command.GetArgumentAtIndex(i), 0, 0, &success);
-                if (!success)
-                {
-                    result.AppendErrorWithFormat ("invalid thread 
specification: \"%s\"\n", command.GetArgumentAtIndex(i));
-                    result.SetStatus (eReturnStatusFailed);
-                    return false;
-                }
-                
-                
thread_sps.push_back(process->GetThreadList().FindThreadByIndexID(thread_idx));
-                
-                if (!thread_sps[i])
-                {
-                    result.AppendErrorWithFormat ("no thread with index: 
\"%s\"\n", command.GetArgumentAtIndex(i));
-                    result.SetStatus (eReturnStatusFailed);
-                    return false;
-                }
-                
-            }
-            
-            for (uint32_t i = 0; i < num_args; i++)
-            {
-                if (!thread_sps[i]->GetStatus (strm,
-                                               m_options.m_start,
-                                               m_options.m_count,
-                                               num_frames_with_source))
-                {
-                    result.AppendErrorWithFormat ("error displaying backtrace 
for thread: \"%s\"\n", command.GetArgumentAtIndex(i));
-                    result.SetStatus (eReturnStatusFailed);
-                    return false;
-                }
-                if (m_options.m_extended_backtrace)
-                {
-                    DoExtendedBacktrace (thread_sps[i].get(), result);
-                }
-                
-                if (i < num_args - 1)
-                    result.AppendMessage("");
-            }
+            DoExtendedBacktrace (&thread, result);
         }
-        return result.Succeeded();
+
+        return true;
     }
 
     CommandOptions m_options;
@@ -379,6 +390,12 @@ public:
                     break;
                 }
                 break;
+            case 'C':
+                {
+                    m_class_name.clear();
+                    m_class_name.assign(option_arg);
+                }
+                break;
             case 'm':
                 {
                     OptionEnumValueElement *enum_values = 
g_option_table[option_idx].enum_values; 
@@ -416,6 +433,7 @@ public:
             m_run_mode = eOnlyDuringStepping;
             m_avoid_regexp.clear();
             m_step_in_target.clear();
+            m_class_name.clear();
             m_step_count = 1;
         }
 
@@ -435,6 +453,7 @@ public:
         RunMode m_run_mode;
         std::string m_avoid_regexp;
         std::string m_step_in_target;
+        std::string m_class_name;
         int32_t m_step_count;
     };
 
@@ -520,6 +539,22 @@ protected:
             }
         }
 
+        if (m_step_type == eStepTypeScripted)
+        {
+            if (m_options.m_class_name.empty())
+            {
+                result.AppendErrorWithFormat ("empty class name for scripted 
step.");
+                result.SetStatus(eReturnStatusFailed);
+                return false;
+            }
+            else if 
(!m_interpreter.GetScriptInterpreter()->CheckObjectExists(m_options.m_class_name.c_str()))
+            {
+                result.AppendErrorWithFormat ("class for scripted step: \"%s\" 
does not exist.", m_options.m_class_name.c_str());
+                result.SetStatus(eReturnStatusFailed);
+                return false;
+            }
+        }
+
         const bool abort_other_plans = false;
         const lldb::RunMode stop_other_threads = m_options.m_run_mode;
         
@@ -530,7 +565,7 @@ protected:
             bool_stop_other_threads = false;
         else if (m_options.m_run_mode == eOnlyDuringStepping)
         {
-            if (m_step_type == eStepTypeOut)
+            if (m_step_type == eStepTypeOut || m_step_type == 
eStepTypeScripted)
                 bool_stop_other_threads = false;
             else
                 bool_stop_other_threads = true;
@@ -599,6 +634,12 @@ protected:
                                                           
thread->GetSelectedFrameIndex(),
                                                           
m_options.m_step_out_avoid_no_debug);
         }
+        else if (m_step_type == eStepTypeScripted)
+        {
+            new_plan_sp = thread->QueueThreadPlanForStepScripted 
(abort_other_plans,
+                                                                  
m_options.m_class_name.c_str(),
+                                                                  
bool_stop_other_threads);
+        }
         else
         {
             result.AppendError ("step type is not supported");
@@ -686,10 +727,11 @@ CommandObjectThreadStepWithTypeAndScope:
 {
 { LLDB_OPT_SET_1, false, "step-in-avoids-no-debug",   'a', 
OptionParser::eRequiredArgument, NULL, NULL,               0, eArgTypeBoolean,  
   "A boolean value that sets whether stepping into functions will step over 
functions with no debug information."},
 { LLDB_OPT_SET_1, false, "step-out-avoids-no-debug",  'A', 
OptionParser::eRequiredArgument, NULL, NULL,               0, eArgTypeBoolean,  
   "A boolean value, if true stepping out of functions will continue to step 
out till it hits a function with debug information."},
-{ LLDB_OPT_SET_1, false, "count",           'c', 
OptionParser::eRequiredArgument, NULL, NULL,               1, eArgTypeCount,    
 "How many times to perform the stepping operation - currently only supported 
for step-inst and next-inst."},
-{ LLDB_OPT_SET_1, false, "run-mode",        'm', 
OptionParser::eRequiredArgument, NULL, g_tri_running_mode, 0, eArgTypeRunMode, 
"Determine how to run other threads while stepping the current thread."},
-{ LLDB_OPT_SET_1, false, "step-over-regexp",'r', 
OptionParser::eRequiredArgument, NULL, NULL,               0, 
eArgTypeRegularExpression,   "A regular expression that defines function names 
to not to stop at when stepping in."},
-{ LLDB_OPT_SET_1, false, "step-in-target",  't', 
OptionParser::eRequiredArgument, NULL, NULL,               0, 
eArgTypeFunctionName,   "The name of the directly called function step in 
should stop at when stepping into."},
+{ LLDB_OPT_SET_1, false, "count",                     'c', 
OptionParser::eRequiredArgument, NULL, NULL,               1, eArgTypeCount,    
 "How many times to perform the stepping operation - currently only supported 
for step-inst and next-inst."},
+{ LLDB_OPT_SET_1, false, "run-mode",                  'm', 
OptionParser::eRequiredArgument, NULL, g_tri_running_mode, 0, eArgTypeRunMode, 
"Determine how to run other threads while stepping the current thread."},
+{ LLDB_OPT_SET_1, false, "step-over-regexp",          'r', 
OptionParser::eRequiredArgument, NULL, NULL,               0, 
eArgTypeRegularExpression,   "A regular expression that defines function names 
to not to stop at when stepping in."},
+{ LLDB_OPT_SET_1, false, "step-in-target",            't', 
OptionParser::eRequiredArgument, NULL, NULL,               0, 
eArgTypeFunctionName,   "The name of the directly called function step in 
should stop at when stepping into."},
+{ LLDB_OPT_SET_2, false, "python-class",              'C', 
OptionParser::eRequiredArgument, NULL, NULL,               0, 
eArgTypePythonClass, "The name of the class that will manage this step - only 
supported for Scripted Step."},
 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
 };
 
@@ -1358,32 +1400,22 @@ protected:
 // CommandObjectThreadInfo
 //-------------------------------------------------------------------------
 
-class CommandObjectThreadInfo : public CommandObjectParsed
+class CommandObjectThreadInfo : public CommandObjectIterateOverThreads
 {
 public:
 
     CommandObjectThreadInfo (CommandInterpreter &interpreter) :
-        CommandObjectParsed (interpreter, 
-                             "thread info",
-                             "Show an extended summary of information about 
thread(s) in a process.",
-                             "thread info",
-                             eFlagRequiresProcess       |
-                             eFlagTryTargetAPILock      |
-                             eFlagProcessMustBeLaunched |
-                             eFlagProcessMustBePaused),
+        CommandObjectIterateOverThreads (interpreter,
+                                         "thread info",
+                                         "Show an extended summary of 
information about thread(s) in a process.",
+                                         "thread info",
+                                         eFlagRequiresProcess       |
+                                         eFlagTryTargetAPILock      |
+                                         eFlagProcessMustBeLaunched |
+                                         eFlagProcessMustBePaused),
         m_options (interpreter)
     {
-        CommandArgumentEntry arg;
-        CommandArgumentData thread_idx_arg;
-        
-        thread_idx_arg.arg_type = eArgTypeThreadIndex;
-        thread_idx_arg.arg_repetition = eArgRepeatStar;
-        
-        // There is only one variant this argument could be; put it into the 
argument entry.
-        arg.push_back (thread_idx_arg);
-        
-        // Push the data for the first argument into the m_arguments vector.
-        m_arguments.push_back (arg);
+        m_add_return = false;
     }
 
     class CommandOptions : public Options
@@ -1451,81 +1483,16 @@ public:
     }
 
     virtual bool
-    DoExecute (Args& command, CommandReturnObject &result)
+    HandleOneThread (Thread &thread, CommandReturnObject &result)
     {
-        result.SetStatus (eReturnStatusSuccessFinishResult);
         Stream &strm = result.GetOutputStream();
-
-        if (command.GetArgumentCount() == 0)
+        if (!thread.GetDescription (strm, eDescriptionLevelFull, 
m_options.m_json))
         {
-            Thread *thread = m_exe_ctx.GetThreadPtr();
-            if (thread->GetDescription (strm, eDescriptionLevelFull, 
m_options.m_json))
-            {
-                result.SetStatus (eReturnStatusSuccessFinishResult);
-            }
-        }
-        else if (command.GetArgumentCount() == 1 && ::strcmp 
(command.GetArgumentAtIndex(0), "all") == 0)
-        {
-            Process *process = m_exe_ctx.GetProcessPtr();
-            uint32_t idx = 0;
-            for (ThreadSP thread_sp : process->Threads())
-            {
-                if (idx != 0)
-                    result.AppendMessage("");
-                if (!thread_sp->GetDescription (strm, eDescriptionLevelFull, 
m_options.m_json))
-                {
-                    result.AppendErrorWithFormat ("error displaying info for 
thread: \"0x%4.4x\"\n", idx);
-                    result.SetStatus (eReturnStatusFailed);
-                    return false;
-                }
-                ++idx;
-            }
-        }
-        else
-        {
-            const size_t num_args = command.GetArgumentCount();
-            Process *process = m_exe_ctx.GetProcessPtr();
-            Mutex::Locker locker (process->GetThreadList().GetMutex());
-            std::vector<ThreadSP> thread_sps;
-
-            for (size_t i = 0; i < num_args; i++)
-            {
-                bool success;
-                
-                uint32_t thread_idx = 
Args::StringToUInt32(command.GetArgumentAtIndex(i), 0, 0, &success);
-                if (!success)
-                {
-                    result.AppendErrorWithFormat ("invalid thread 
specification: \"%s\"\n", command.GetArgumentAtIndex(i));
-                    result.SetStatus (eReturnStatusFailed);
-                    return false;
-                }
-                
-                
thread_sps.push_back(process->GetThreadList().FindThreadByIndexID(thread_idx));
-                
-                if (!thread_sps[i])
-                {
-                    result.AppendErrorWithFormat ("no thread with index: 
\"%s\"\n", command.GetArgumentAtIndex(i));
-                    result.SetStatus (eReturnStatusFailed);
-                    return false;
-                }
-                
-            }
-            
-            for (uint32_t i = 0; i < num_args; i++)
-            {
-                if (!thread_sps[i]->GetDescription (strm, 
eDescriptionLevelFull, m_options.m_json))
-                {
-                    result.AppendErrorWithFormat ("error displaying info for 
thread: \"%s\"\n", command.GetArgumentAtIndex(i));
-                    result.SetStatus (eReturnStatusFailed);
-                    return false;
-                }
-                
-                if (i < num_args - 1)
-                    result.AppendMessage("");
-            }
-
+            result.AppendErrorWithFormat ("error displaying info for thread: 
\"%d\"\n", thread.GetIndexID());
+            result.SetStatus (eReturnStatusFailed);
+            return false;
         }
-        return result.Succeeded();
+        return true;
     }
 
     CommandOptions m_options;
@@ -1958,6 +1925,228 @@ CommandObjectThreadJump::CommandOptions:
 };
 
 //-------------------------------------------------------------------------
+// Next are the subcommands of CommandObjectMultiwordThreadPlan
+//-------------------------------------------------------------------------
+
+
+//-------------------------------------------------------------------------
+// CommandObjectThreadPlanList
+//-------------------------------------------------------------------------
+class CommandObjectThreadPlanList : public CommandObjectIterateOverThreads
+{
+public:
+
+    class CommandOptions : public Options
+    {
+    public:
+
+        CommandOptions (CommandInterpreter &interpreter) :
+            Options(interpreter)
+        {
+            // Keep default values of all options in one place: 
OptionParsingStarting ()
+            OptionParsingStarting ();
+        }
+
+        virtual
+        ~CommandOptions ()
+        {
+        }
+
+        virtual Error
+        SetOptionValue (uint32_t option_idx, const char *option_arg)
+        {
+            Error error;
+            const int short_option = m_getopt_table[option_idx].val;
+
+            switch (short_option)
+            {
+                case 'i':
+                {
+                    m_internal = true;
+                }
+                break;
+                case 'v':
+                {
+                    m_verbose = true;
+                }
+                break;
+                default:
+                    error.SetErrorStringWithFormat("invalid short option 
character '%c'", short_option);
+                    break;
+
+            }
+            return error;
+        }
+
+        void
+        OptionParsingStarting ()
+        {
+            m_verbose = false;
+            m_internal = false;
+        }
+
+        const OptionDefinition*
+        GetDefinitions ()
+        {
+            return g_option_table;
+        }
+
+        // Options table: Required for subclasses of Options.
+
+        static OptionDefinition g_option_table[];
+
+        // Instance variables to hold the values for command options.
+        bool m_verbose;
+        bool m_internal;
+    };
+
+    CommandObjectThreadPlanList (CommandInterpreter &interpreter) :
+        CommandObjectIterateOverThreads (interpreter,
+                                         "thread plan list",
+                                         "Show thread plans for one or more 
threads.  If no threads are specified, show the "
+                                         "currently selected thread.  Use the 
thread-index \"all\" to see all threads.",
+                                         NULL,
+                                         eFlagRequiresProcess       |
+                                         eFlagRequiresThread        |
+                                         eFlagTryTargetAPILock      |
+                                         eFlagProcessMustBeLaunched |
+                                         eFlagProcessMustBePaused   ),
+        m_options(interpreter)
+    {
+    }
+
+    ~CommandObjectThreadPlanList ()
+    {
+    }
+
+    virtual Options *
+    GetOptions ()
+    {
+        return &m_options;
+    }
+
+protected:
+    virtual bool
+    HandleOneThread (Thread &thread, CommandReturnObject &result)
+    {
+        Stream &strm = result.GetOutputStream();
+        DescriptionLevel desc_level = eDescriptionLevelFull;
+        if (m_options.m_verbose)
+            desc_level = eDescriptionLevelVerbose;
+
+        thread.DumpThreadPlans (&strm, desc_level, m_options.m_internal, true);
+        return true;
+    }
+    CommandOptions m_options;
+};
+
+OptionDefinition
+CommandObjectThreadPlanList::CommandOptions::g_option_table[] =
+{
+{ LLDB_OPT_SET_1, false, "verbose", 'v', OptionParser::eNoArgument, NULL, 
NULL, 0, eArgTypeNone, "Display more information about the thread plans"},
+{ LLDB_OPT_SET_1, false, "internal", 'i', OptionParser::eNoArgument, NULL, 
NULL, 0, eArgTypeNone, "Display internal as well as user thread plans"},
+{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
+};
+
+class CommandObjectThreadPlanDiscard : public CommandObjectParsed
+{
+public:
+    CommandObjectThreadPlanDiscard (CommandInterpreter &interpreter) :
+        CommandObjectParsed (interpreter,
+                             "thread plan discard",
+                             "Discards thread plans up to and including the 
plan passed as the command argument."
+                             "Only user visible plans can be discarded, use 
the index from \"thread plan list\""
+                             " without the \"-i\" argument.",
+                             NULL,
+                             eFlagRequiresProcess       |
+                             eFlagRequiresThread        |
+                             eFlagTryTargetAPILock      |
+                             eFlagProcessMustBeLaunched |
+                             eFlagProcessMustBePaused   )
+    {
+        CommandArgumentEntry arg;
+        CommandArgumentData plan_index_arg;
+
+        // Define the first (and only) variant of this arg.
+        plan_index_arg.arg_type = eArgTypeUnsignedInteger;
+        plan_index_arg.arg_repetition = eArgRepeatPlain;
+
+        // There is only one variant this argument could be; put it into the 
argument entry.
+        arg.push_back (plan_index_arg);
+
+        // Push the data for the first argument into the m_arguments vector.
+        m_arguments.push_back (arg);
+    }
+
+    virtual ~CommandObjectThreadPlanDiscard () {}
+
+    bool
+    DoExecute (Args& args, CommandReturnObject &result)
+    {
+        Thread *thread = m_exe_ctx.GetThreadPtr();
+        if (args.GetArgumentCount() != 1)
+        {
+            result.AppendErrorWithFormat("Too many arguments, expected one - 
the thread plan index - but got %zu.",
+                                         args.GetArgumentCount());
+            result.SetStatus (eReturnStatusFailed);
+            return false;
+        }
+
+        bool success;
+        uint32_t thread_plan_idx = 
Args::StringToUInt32(args.GetArgumentAtIndex(0), 0, 0, &success);
+        if (!success)
+        {
+            result.AppendErrorWithFormat("Invalid thread index: \"%s\" - 
should be unsigned int.",
+                                         args.GetArgumentAtIndex(0));
+            result.SetStatus (eReturnStatusFailed);
+            return false;
+        }
+
+        if (thread_plan_idx == 0)
+        {
+            result.AppendErrorWithFormat("You wouldn't really want me to 
discard the base thread plan.");
+            result.SetStatus (eReturnStatusFailed);
+            return false;
+        }
+
+        if (thread->DiscardUserThreadPlansUpToIndex(thread_plan_idx))
+        {
+            result.SetStatus(eReturnStatusSuccessFinishNoResult);
+            return true;
+        }
+        else
+        {
+            result.AppendErrorWithFormat("Could not find User thread plan with 
index %s.",
+                                         args.GetArgumentAtIndex(0));
+            result.SetStatus (eReturnStatusFailed);
+            return false;
+        }
+    }
+};
+
+//-------------------------------------------------------------------------
+// CommandObjectMultiwordThreadPlan
+//-------------------------------------------------------------------------
+
+class CommandObjectMultiwordThreadPlan : public CommandObjectMultiword
+{
+public:
+    CommandObjectMultiwordThreadPlan(CommandInterpreter &interpreter) :
+        CommandObjectMultiword (interpreter,
+                                "plan",
+                                "A set of subcommands for accessing the thread 
plans controlling execution control on one or more threads.",
+                                "thread plan <subcommand> [<subcommand 
objects]")
+    {
+        LoadSubCommand ("list", CommandObjectSP (new 
CommandObjectThreadPlanList (interpreter)));
+        LoadSubCommand ("discard", CommandObjectSP (new 
CommandObjectThreadPlanDiscard (interpreter)));
+    }
+
+    virtual ~CommandObjectMultiwordThreadPlan () {}
+
+
+};
+
+//-------------------------------------------------------------------------
 // CommandObjectMultiwordThread
 //-------------------------------------------------------------------------
 
@@ -2014,6 +2203,16 @@ CommandObjectMultiwordThread::CommandObj
                                                     NULL,
                                                     eStepTypeTraceOver,
                                                     eStepScopeInstruction)));
+
+    LoadSubCommand ("step-scripted", CommandObjectSP (new 
CommandObjectThreadStepWithTypeAndScope (
+                                                    interpreter,
+                                                    "thread step-scripted",
+                                                    "Step as instructed by the 
script class passed in the -C option.",
+                                                    NULL,
+                                                    eStepTypeScripted,
+                                                    eStepScopeSource)));
+
+    LoadSubCommand ("plan", CommandObjectSP (new 
CommandObjectMultiwordThreadPlan(interpreter)));
 }
 
 CommandObjectMultiwordThread::~CommandObjectMultiwordThread ()

Modified: lldb/trunk/source/Expression/ClangFunction.cpp
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangFunction.cpp?rev=218642&r1=218641&r2=218642&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangFunction.cpp (original)
+++ lldb/trunk/source/Expression/ClangFunction.cpp Mon Sep 29 18:17:18 2014
@@ -422,7 +422,7 @@ ClangFunction::InsertFunction (Execution
     return true;
 }
 
-ThreadPlan *
+lldb::ThreadPlanSP
 ClangFunction::GetThreadPlanToCallFunction (ExecutionContext &exe_ctx, 
                                             lldb::addr_t args_addr,
                                             const EvaluateExpressionOptions 
&options,
@@ -447,14 +447,14 @@ ClangFunction::GetThreadPlanToCallFuncti
     
     lldb::addr_t args = { args_addr };
     
-    ThreadPlan *new_plan = new ThreadPlanCallFunction (*thread, 
+    lldb::ThreadPlanSP new_plan_sp (new ThreadPlanCallFunction (*thread,
                                                        wrapper_address,
                                                        ClangASTType(),
                                                        args,
-                                                       options);
-    new_plan->SetIsMasterPlan(true);
-    new_plan->SetOkayToDiscard (false);
-    return new_plan;
+                                                       options));
+    new_plan_sp->SetIsMasterPlan(true);
+    new_plan_sp->SetOkayToDiscard (false);
+    return new_plan_sp;
 }
 
 bool
@@ -541,10 +541,10 @@ ClangFunction::ExecuteFunction(
     if (log)
         log->Printf("== [ClangFunction::ExecuteFunction] Executing function 
\"%s\" ==", m_name.c_str());
     
-    lldb::ThreadPlanSP call_plan_sp (GetThreadPlanToCallFunction (exe_ctx,
-                                                                  args_addr,
-                                                                  real_options,
-                                                                  errors));
+    lldb::ThreadPlanSP call_plan_sp = GetThreadPlanToCallFunction (exe_ctx,
+                                                                   args_addr,
+                                                                   
real_options,
+                                                                   errors);
     if (!call_plan_sp)
         return lldb::eExpressionSetupError;
         

Modified: lldb/trunk/source/Expression/ClangUserExpression.cpp
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangUserExpression.cpp?rev=218642&r1=218641&r2=218642&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangUserExpression.cpp (original)
+++ lldb/trunk/source/Expression/ClangUserExpression.cpp Mon Sep 29 18:17:18 
2014
@@ -885,17 +885,17 @@ ClangUserExpression::Execute (Stream &er
 
             args.push_back(struct_address);
          
-            ThreadPlanCallUserExpression *user_expression_plan = 
-                    new ThreadPlanCallUserExpression (exe_ctx.GetThreadRef(),
-                                                      wrapper_address, 
-                                                      args,
-                                                      options,
-                                                      shared_ptr_to_me);
-            lldb::ThreadPlanSP call_plan_sp(user_expression_plan);
+            lldb::ThreadPlanSP call_plan_sp(new ThreadPlanCallUserExpression 
(exe_ctx.GetThreadRef(),
+                                                                              
wrapper_address,
+                                                                              
args,
+                                                                              
options,
+                                                                              
shared_ptr_to_me));
 
             if (!call_plan_sp || !call_plan_sp->ValidatePlan (&error_stream))
                 return lldb::eExpressionSetupError;
 
+            ThreadPlanCallUserExpression *user_expression_plan = 
static_cast<ThreadPlanCallUserExpression *>(call_plan_sp.get());
+
             lldb::addr_t function_stack_pointer = 
user_expression_plan->GetFunctionStackPointer();
 
             function_stack_bottom = function_stack_pointer - 
HostInfo::GetPageSize();

Modified: lldb/trunk/source/Interpreter/ScriptInterpreter.cpp
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/ScriptInterpreter.cpp?rev=218642&r1=218641&r2=218642&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/ScriptInterpreter.cpp (original)
+++ lldb/trunk/source/Interpreter/ScriptInterpreter.cpp Mon Sep 29 18:17:18 2014
@@ -131,7 +131,9 @@ ScriptInterpreter::InitializeInterpreter
                                           SWIGPythonScriptKeyword_Thread 
swig_run_script_keyword_thread,
                                           SWIGPythonScriptKeyword_Target 
swig_run_script_keyword_target,
                                           SWIGPythonScriptKeyword_Frame 
swig_run_script_keyword_frame,
-                                          SWIGPython_GetDynamicSetting 
swig_plugin_get)
+                                          SWIGPython_GetDynamicSetting 
swig_plugin_get,
+                                          SWIGPythonCreateScriptedThreadPlan 
swig_thread_plan_script,
+                                          SWIGPythonCallThreadPlan 
swig_call_thread_plan)
 {
 #ifndef LLDB_DISABLE_PYTHON
     ScriptInterpreterPython::InitializeInterpreter (python_swig_init_callback,
@@ -153,6 +155,8 @@ ScriptInterpreter::InitializeInterpreter
                                                     
swig_run_script_keyword_thread,
                                                     
swig_run_script_keyword_target,
                                                     
swig_run_script_keyword_frame,
-                                                    swig_plugin_get);
+                                                    swig_plugin_get,
+                                                    swig_thread_plan_script,
+                                                    swig_call_thread_plan);
 #endif // #ifndef LLDB_DISABLE_PYTHON
 }

Modified: lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp?rev=218642&r1=218641&r2=218642&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp (original)
+++ lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp Mon Sep 29 
18:17:18 2014
@@ -37,6 +37,7 @@
 #include "lldb/Interpreter/CommandReturnObject.h"
 #include "lldb/Interpreter/PythonDataObjects.h"
 #include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadPlan.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -62,6 +63,8 @@ static ScriptInterpreter::SWIGPythonScri
 static ScriptInterpreter::SWIGPythonScriptKeyword_Target 
g_swig_run_script_keyword_target = nullptr;
 static ScriptInterpreter::SWIGPythonScriptKeyword_Frame 
g_swig_run_script_keyword_frame = nullptr;
 static ScriptInterpreter::SWIGPython_GetDynamicSetting g_swig_plugin_get = 
nullptr;
+static ScriptInterpreter::SWIGPythonCreateScriptedThreadPlan 
g_swig_thread_plan_script = nullptr;
+static ScriptInterpreter::SWIGPythonCallThreadPlan g_swig_call_thread_plan = 
nullptr;
 
 static std::string
 ReadPythonBacktrace (PyObject* py_backtrace);
@@ -1617,6 +1620,87 @@ ScriptInterpreterPython::OSPlugin_Create
 }
 
 lldb::ScriptInterpreterObjectSP
+ScriptInterpreterPython::CreateScriptedThreadPlan (const char *class_name,
+                              lldb::ThreadPlanSP thread_plan_sp)
+{
+    if (class_name == nullptr || class_name[0] == '\0')
+        return lldb::ScriptInterpreterObjectSP();
+    
+    if (!thread_plan_sp.get())
+        return lldb::ScriptInterpreterObjectSP();
+
+    Debugger &debugger = thread_plan_sp->GetTarget().GetDebugger();
+    ScriptInterpreter *script_interpreter = 
debugger.GetCommandInterpreter().GetScriptInterpreter();
+    ScriptInterpreterPython *python_interpreter = 
static_cast<ScriptInterpreterPython *>(script_interpreter);
+    
+    if (!script_interpreter)
+        return lldb::ScriptInterpreterObjectSP();
+    
+    void* ret_val;
+
+    {
+        Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | 
Locker::NoSTDIN);
+        
+        ret_val = g_swig_thread_plan_script (class_name,
+                                             
python_interpreter->m_dictionary_name.c_str(),
+                                             thread_plan_sp);
+    }
+    
+    return MakeScriptObject(ret_val);
+}
+
+bool
+ScriptInterpreterPython::ScriptedThreadPlanExplainsStop 
(lldb::ScriptInterpreterObjectSP implementor_sp,
+                                Event *event,
+                                bool &script_error)
+{
+    bool explains_stop = true;
+    if (implementor_sp)
+    {
+        Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | 
Locker::NoSTDIN);
+        explains_stop = g_swig_call_thread_plan (implementor_sp->GetObject(), 
"explains_stop", event, script_error);
+        if (script_error)
+            return true;
+    }
+    return explains_stop;
+}
+
+bool
+ScriptInterpreterPython::ScriptedThreadPlanShouldStop 
(lldb::ScriptInterpreterObjectSP implementor_sp,
+                              Event *event,
+                              bool &script_error)
+{
+    bool should_stop = true;
+    if (implementor_sp)
+    {
+        Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | 
Locker::NoSTDIN);
+        should_stop = g_swig_call_thread_plan (implementor_sp->GetObject(), 
"should_stop", event, script_error);
+        if (script_error)
+            return true;
+    }
+    return should_stop;
+}
+
+lldb::StateType
+ScriptInterpreterPython::ScriptedThreadPlanGetRunState 
(lldb::ScriptInterpreterObjectSP implementor_sp,
+                                                        bool &script_error)
+{
+    bool should_step = false;
+    if (implementor_sp)
+    {
+        Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | 
Locker::NoSTDIN);
+        should_step = g_swig_call_thread_plan (implementor_sp->GetObject(), 
"should_step", NULL, script_error);
+        if (script_error)
+            should_step = true;
+    }
+    if (should_step)
+        return lldb::eStateStepping;
+    else
+        return lldb::eStateRunning;
+}
+
+
+lldb::ScriptInterpreterObjectSP
 ScriptInterpreterPython::LoadPluginModule (const FileSpec& file_spec,
                                            lldb_private::Error& error)
 {
@@ -2536,7 +2620,9 @@ ScriptInterpreterPython::InitializeInter
                                                 SWIGPythonScriptKeyword_Thread 
swig_run_script_keyword_thread,
                                                 SWIGPythonScriptKeyword_Target 
swig_run_script_keyword_target,
                                                 SWIGPythonScriptKeyword_Frame 
swig_run_script_keyword_frame,
-                                                SWIGPython_GetDynamicSetting 
swig_plugin_get)
+                                                SWIGPython_GetDynamicSetting 
swig_plugin_get,
+                                                
SWIGPythonCreateScriptedThreadPlan swig_thread_plan_script,
+                                                SWIGPythonCallThreadPlan 
swig_call_thread_plan)
 {
     g_swig_init_callback = swig_init_callback;
     g_swig_breakpoint_callback = swig_breakpoint_callback;
@@ -2558,6 +2644,8 @@ ScriptInterpreterPython::InitializeInter
     g_swig_run_script_keyword_target = swig_run_script_keyword_target;
     g_swig_run_script_keyword_frame = swig_run_script_keyword_frame;
     g_swig_plugin_get = swig_plugin_get;
+    g_swig_thread_plan_script = swig_thread_plan_script;
+    g_swig_call_thread_plan = swig_call_thread_plan;
 }
 
 void

Modified: 
lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp?rev=218642&r1=218641&r2=218642&view=diff
==============================================================================
--- 
lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp
 (original)
+++ 
lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp
 Mon Sep 29 18:17:18 2014
@@ -89,10 +89,10 @@ AppleThreadPlanStepThroughObjCTrampoline
         options.SetIgnoreBreakpoints(true);
         options.SetStopOthers(m_stop_others);
         m_thread.CalculateExecutionContext(exc_ctx);
-        m_func_sp.reset(m_impl_function->GetThreadPlanToCallFunction (exc_ctx,
-                                                                      
m_args_addr,
-                                                                      options,
-                                                                      errors));
+        m_func_sp = m_impl_function->GetThreadPlanToCallFunction (exc_ctx,
+                                                                  m_args_addr,
+                                                                  options,
+                                                                  errors);
         m_func_sp->SetOkayToDiscard(true);
         m_thread.QueueThreadPlan (m_func_sp, false);
     }

Modified: lldb/trunk/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp?rev=218642&r1=218641&r2=218642&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp Mon Sep 29 
18:17:18 2014
@@ -98,13 +98,11 @@ lldb_private::InferiorCallMmap (Process
                 ClangASTContext *clang_ast_context = 
process->GetTarget().GetScratchClangASTContext();
                 ClangASTType clang_void_ptr_type = 
clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
                 lldb::addr_t args[] = { addr, length, prot_arg, flags_arg, fd, 
offset };
-                ThreadPlanCallFunction *call_function_thread_plan
-                  = new ThreadPlanCallFunction (*thread,
-                                                mmap_range.GetBaseAddress(),
-                                                clang_void_ptr_type,
-                                                args,
-                                                options);
-                lldb::ThreadPlanSP call_plan_sp (call_function_thread_plan);
+                lldb::ThreadPlanSP call_plan_sp (new ThreadPlanCallFunction 
(*thread,
+                                                                             
mmap_range.GetBaseAddress(),
+                                                                             
clang_void_ptr_type,
+                                                                             
args,
+                                                                             
options));
                 if (call_plan_sp)
                 {
                     StreamFile error_strm;
@@ -241,13 +239,11 @@ lldb_private::InferiorCall (Process *pro
 
     ClangASTContext *clang_ast_context = 
process->GetTarget().GetScratchClangASTContext();
     ClangASTType clang_void_ptr_type = 
clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
-    ThreadPlanCallFunction *call_function_thread_plan
-        = new ThreadPlanCallFunction (*thread,
-                                      *address,
-                                      clang_void_ptr_type,
-                                      llvm::ArrayRef<addr_t>(),
-                                      options);
-    lldb::ThreadPlanSP call_plan_sp (call_function_thread_plan);
+    lldb::ThreadPlanSP call_plan_sp (new ThreadPlanCallFunction (*thread,
+                                                                 *address,
+                                                                 
clang_void_ptr_type,
+                                                                 
llvm::ArrayRef<addr_t>(),
+                                                                 options));
     if (call_plan_sp)
     {
         StreamString error_strm;

Modified: lldb/trunk/source/Target/Thread.cpp
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Thread.cpp?rev=218642&r1=218641&r2=218642&view=diff
==============================================================================
--- lldb/trunk/source/Target/Thread.cpp (original)
+++ lldb/trunk/source/Target/Thread.cpp Mon Sep 29 18:17:18 2014
@@ -32,6 +32,7 @@
 #include "lldb/Target/ThreadPlan.h"
 #include "lldb/Target/ThreadPlanCallFunction.h"
 #include "lldb/Target/ThreadPlanBase.h"
+#include "lldb/Target/ThreadPlanPython.h"
 #include "lldb/Target/ThreadPlanStepInstruction.h"
 #include "lldb/Target/ThreadPlanStepOut.h"
 #include "lldb/Target/ThreadPlanStepOverBreakpoint.h"
@@ -652,17 +653,18 @@ Thread::SetupForResume ()
 
                 if (cur_plan->GetKind() != ThreadPlan::eKindStepOverBreakpoint)
                 {
-                    ThreadPlanStepOverBreakpoint *step_bp_plan = new 
ThreadPlanStepOverBreakpoint (*this);
-                    if (step_bp_plan)
+                    ThreadPlanSP step_bp_plan_sp (new 
ThreadPlanStepOverBreakpoint (*this));
+                    if (step_bp_plan_sp)
                     {
-                        ThreadPlanSP step_bp_plan_sp;
-                        step_bp_plan->SetPrivate (true);
+                        ;
+                        step_bp_plan_sp->SetPrivate (true);
 
                         if (GetCurrentPlan()->RunState() != eStateStepping)
                         {
+                            ThreadPlanStepOverBreakpoint *step_bp_plan
+                                    = static_cast<ThreadPlanStepOverBreakpoint 
*>(step_bp_plan_sp.get());
                             step_bp_plan->SetAutoContinue(true);
                         }
-                        step_bp_plan_sp.reset (step_bp_plan);
                         QueueThreadPlan (step_bp_plan_sp, false);
                     }
                 }
@@ -1290,6 +1292,36 @@ Thread::SetTracer (lldb::ThreadPlanTrace
         m_plan_stack[i]->SetThreadPlanTracer(tracer_sp);
 }
 
+bool
+Thread::DiscardUserThreadPlansUpToIndex (uint32_t thread_index)
+{
+    // Count the user thread plans from the back end to get the number of the 
one we want
+    // to discard:
+
+    uint32_t idx = 0;
+    ThreadPlan *up_to_plan_ptr = nullptr;
+
+    for (ThreadPlanSP plan_sp : m_plan_stack)
+    {
+        if (plan_sp->GetPrivate())
+            continue;
+        if (idx == thread_index)
+        {
+            up_to_plan_ptr = plan_sp.get();
+            break;
+        }
+        else
+            idx++;
+    }
+
+    if (up_to_plan_ptr == nullptr)
+        return false;
+
+    DiscardThreadPlansUpToPlan(up_to_plan_ptr);
+    return true;
+}
+    
+
 void
 Thread::DiscardThreadPlansUpToPlan (lldb::ThreadPlanSP &up_to_plan_sp)
 {
@@ -1483,18 +1515,16 @@ Thread::QueueThreadPlanForStepInRange
     LazyBool step_out_avoids_code_without_debug_info
 )
 {
-    ThreadPlanSP thread_plan_sp;
-    ThreadPlanStepInRange *plan = new ThreadPlanStepInRange (*this,
+    ThreadPlanSP thread_plan_sp (new ThreadPlanStepInRange (*this,
                                                              range,
                                                              addr_context,
                                                              
stop_other_threads,
                                                              
step_in_avoids_code_without_debug_info,
-                                                             
step_out_avoids_code_without_debug_info);
+                                                             
step_out_avoids_code_without_debug_info));
+    ThreadPlanStepInRange *plan = static_cast<ThreadPlanStepInRange 
*>(thread_plan_sp.get());
     
     if (step_in_target)
         plan->SetStepInTarget(step_in_target);
-    
-    thread_plan_sp.reset (plan);
 
     QueueThreadPlan (thread_plan_sp, abort_other_plans);
     return thread_plan_sp;
@@ -1546,17 +1576,18 @@ Thread::QueueThreadPlanForStepOutNoShoul
     uint32_t frame_idx
 )
 {
-    ThreadPlanStepOut *new_plan = new ThreadPlanStepOut (*this,
+    ThreadPlanSP thread_plan_sp(new ThreadPlanStepOut (*this,
                                                         addr_context, 
                                                         first_insn, 
                                                         stop_other_threads, 
                                                         stop_vote, 
                                                         run_vote, 
                                                         frame_idx,
-                                                        eLazyBoolNo);
+                                                        eLazyBoolNo));
+
+    ThreadPlanStepOut *new_plan = static_cast<ThreadPlanStepOut 
*>(thread_plan_sp.get());
     new_plan->ClearShouldStopHereCallbacks();
-    ThreadPlanSP thread_plan_sp(new_plan);
-    
+
     if (thread_plan_sp->ValidatePlan(NULL))
     {
         QueueThreadPlan (thread_plan_sp, abort_other_plans);
@@ -1602,61 +1633,105 @@ Thread::QueueThreadPlanForStepUntil (boo
 
 }
 
+lldb::ThreadPlanSP
+Thread::QueueThreadPlanForStepScripted (bool abort_other_plans,
+                                        const char *class_name,
+                                        bool stop_other_threads)
+{
+    ThreadPlanSP thread_plan_sp (new ThreadPlanPython (*this, class_name));
+    QueueThreadPlan (thread_plan_sp, abort_other_plans);
+    // This seems a little funny, but I don't want to have to split up the 
constructor and the
+    // DidPush in the scripted plan, that seems annoying.
+    // That means the constructor has to be in DidPush.
+    // So I have to validate the plan AFTER pushing it, and then take it off 
again...
+    if (!thread_plan_sp->ValidatePlan(nullptr))
+    {
+        DiscardThreadPlansUpToPlan(thread_plan_sp);
+        return ThreadPlanSP();
+    }
+    else
+        return thread_plan_sp;
+
+}
+
 uint32_t
 Thread::GetIndexID () const
 {
     return m_index_id;
 }
 
-void
-Thread::DumpThreadPlans (lldb_private::Stream *s) const
+static void
+PrintPlanElement (Stream *s, const ThreadPlanSP &plan, lldb::DescriptionLevel 
desc_level, int32_t elem_idx)
 {
-    uint32_t stack_size = m_plan_stack.size();
-    int i;
-    s->Indent();
-    s->Printf ("Plan Stack for thread #%u: tid = 0x%4.4" PRIx64 ", stack_size 
= %d\n", GetIndexID(), GetID(), stack_size);
-    for (i = stack_size - 1; i >= 0; i--)
-    {
         s->IndentMore();
         s->Indent();
-        s->Printf ("Element %d: ", i);
-        m_plan_stack[i]->GetDescription (s, eDescriptionLevelFull);
+        s->Printf ("Element %d: ", elem_idx);
+        plan->GetDescription (s, desc_level);
         s->EOL();
         s->IndentLess();
+}
+
+static void
+PrintPlanStack (Stream *s, const std::vector<lldb::ThreadPlanSP> &plan_stack, 
lldb::DescriptionLevel desc_level, bool include_internal)
+{
+    int32_t print_idx = 0;
+    for (ThreadPlanSP plan_sp : plan_stack)
+    {
+        if (include_internal || !plan_sp->GetPrivate())
+        {
+            PrintPlanElement (s, plan_sp, desc_level, print_idx++);
+        }
     }
+}
 
-    stack_size = m_completed_plan_stack.size();
-    if (stack_size > 0)
+void
+Thread::DumpThreadPlans (Stream *s,
+                         lldb::DescriptionLevel desc_level,
+                         bool include_internal,
+                         bool ignore_boring_threads) const
+{
+    uint32_t stack_size = m_plan_stack.size();
+
+    if (ignore_boring_threads)
     {
-        s->Indent();
-        s->Printf ("Completed Plan Stack: %d elements.\n", stack_size);
-        for (i = stack_size - 1; i >= 0; i--)
+        uint32_t stack_size = m_plan_stack.size();
+        uint32_t completed_stack_size = m_completed_plan_stack.size();
+        uint32_t discarded_stack_size = m_discarded_plan_stack.size();
+        if (stack_size == 1 && completed_stack_size == 0 && 
discarded_stack_size == 0)
         {
+            s->Printf ("thread #%u: tid = 0x%4.4" PRIx64 "\n", GetIndexID(), 
GetID());
             s->IndentMore();
             s->Indent();
-            s->Printf ("Element %d: ", i);
-            m_completed_plan_stack[i]->GetDescription (s, 
eDescriptionLevelFull);
-            s->EOL();
+            s->Printf("No active thread plans\n");
             s->IndentLess();
+            return;
         }
     }
 
+    s->Indent();
+    s->Printf ("thread #%u: tid = 0x%4.4" PRIx64 ":\n", GetIndexID(), GetID());
+    s->IndentMore();
+    s->Indent();
+    s->Printf ("Active plan stack:\n");
+    PrintPlanStack (s, m_plan_stack, desc_level, include_internal);
+
+    stack_size = m_completed_plan_stack.size();
+    if (stack_size > 0)
+    {
+        s->Indent();
+        s->Printf ("Completed Plan Stack:\n");
+        PrintPlanStack (s, m_completed_plan_stack, desc_level, 
include_internal);
+    }
+
     stack_size = m_discarded_plan_stack.size();
     if (stack_size > 0)
     {
         s->Indent();
-        s->Printf ("Discarded Plan Stack: %d elements.\n", stack_size);
-        for (i = stack_size - 1; i >= 0; i--)
-        {
-            s->IndentMore();
-            s->Indent();
-            s->Printf ("Element %d: ", i);
-            m_discarded_plan_stack[i]->GetDescription (s, 
eDescriptionLevelFull);
-            s->EOL();
-            s->IndentLess();
-        }
+        s->Printf ("Discarded Plan Stack:\n");
+        PrintPlanStack (s, m_discarded_plan_stack, desc_level, 
include_internal);
     }
 
+    s->IndentLess();
 }
 
 TargetSP

Added: lldb/trunk/source/Target/ThreadPlanPython.cpp
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlanPython.cpp?rev=218642&view=auto
==============================================================================
--- lldb/trunk/source/Target/ThreadPlanPython.cpp (added)
+++ lldb/trunk/source/Target/ThreadPlanPython.cpp Mon Sep 29 18:17:18 2014
@@ -0,0 +1,192 @@
+//===-- ThreadPlan.cpp ------------------------------------------*- C++ 
-*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/lldb-python.h"
+
+#include "lldb/Target/ThreadPlan.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/Debugger.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/State.h"
+#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Interpreter/ScriptInterpreter.h"
+#include "lldb/Interpreter/ScriptInterpreterPython.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadPlan.h"
+#include "lldb/Target/ThreadPlanPython.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Target.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+//----------------------------------------------------------------------
+// ThreadPlanPython
+//----------------------------------------------------------------------
+
+ThreadPlanPython::ThreadPlanPython (Thread &thread, const char *class_name) :
+    ThreadPlan (ThreadPlan::eKindPython,
+                "Python based Thread Plan",
+                thread,
+                eVoteNoOpinion,
+                eVoteNoOpinion),
+    m_class_name (class_name)
+{
+    SetIsMasterPlan (true);
+    SetOkayToDiscard (true);
+    SetPrivate (false);
+}
+
+ThreadPlanPython::~ThreadPlanPython ()
+{
+    // FIXME, do I need to decrement the ref count on this implementation 
object to make it go away?
+}
+
+bool
+ThreadPlanPython::ValidatePlan (Stream *error)
+{
+    // I have to postpone setting up the implementation till after the 
constructor because I need to call
+    // shared_from_this, which you can't do in the constructor.  So I'll do it 
here.
+    if (m_implementation_sp)
+        return true;
+    else
+        return false;
+}
+
+void
+ThreadPlanPython::DidPush()
+{
+    // We set up the script side in DidPush, so that it can push other plans 
in the constructor,
+    // and doesn't have to care about the details of DidPush.
+
+    if (!m_class_name.empty())
+    {
+        ScriptInterpreter *script_interp = 
m_thread.GetProcess()->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
+        if (script_interp)
+        {
+            m_implementation_sp = script_interp->CreateScriptedThreadPlan 
(m_class_name.c_str(), this->shared_from_this());
+        }
+    }
+}
+
+bool
+ThreadPlanPython::ShouldStop (Event *event_ptr)
+{
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
+    if (log)
+        log->Printf ("%s called on Python Thread Plan: %s )",
+                    __PRETTY_FUNCTION__, m_class_name.c_str());
+
+    bool should_stop = true;
+    if (m_implementation_sp)
+    {
+        ScriptInterpreter *script_interp = 
m_thread.GetProcess()->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
+        if (script_interp)
+        {
+            bool script_error;
+            should_stop = script_interp->ScriptedThreadPlanShouldStop 
(m_implementation_sp, event_ptr, script_error);
+            if (script_error)
+                SetPlanComplete(false);
+        }
+    }
+    return should_stop;
+}
+
+bool
+ThreadPlanPython::DoPlanExplainsStop (Event *event_ptr)
+{
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
+    if (log)
+        log->Printf ("%s called on Python Thread Plan: %s )",
+                    __PRETTY_FUNCTION__, m_class_name.c_str());
+
+    bool explains_stop = true;
+    if (m_implementation_sp)
+    {
+        ScriptInterpreter *script_interp = 
m_thread.GetProcess()->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
+        if (script_interp)
+        {
+            bool script_error;
+            explains_stop = script_interp->ScriptedThreadPlanExplainsStop 
(m_implementation_sp, event_ptr, script_error);
+            if (script_error)
+                SetPlanComplete(false);
+        }
+    }
+    return explains_stop;
+}
+
+bool
+ThreadPlanPython::MischiefManaged ()
+{
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
+    if (log)
+        log->Printf ("%s called on Python Thread Plan: %s )",
+                    __PRETTY_FUNCTION__, m_class_name.c_str());
+    bool mischief_managed = true;
+    if (m_implementation_sp)
+    {
+        // I don't really need mischief_managed, since it's simpler to just 
call SetPlanComplete in should_stop.
+        mischief_managed = IsPlanComplete();
+        if (mischief_managed)
+            m_implementation_sp.reset();
+    }
+    return mischief_managed;
+}
+
+lldb::StateType
+ThreadPlanPython::GetPlanRunState ()
+{
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
+    if (log)
+        log->Printf ("%s called on Python Thread Plan: %s )",
+                     __PRETTY_FUNCTION__,
+                     m_class_name.c_str());
+    lldb::StateType run_state = eStateRunning;
+    if (m_implementation_sp)
+    {
+        ScriptInterpreter *script_interp = 
m_thread.GetProcess()->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
+        if (script_interp)
+        {
+            bool script_error;
+            run_state = script_interp->ScriptedThreadPlanGetRunState 
(m_implementation_sp, script_error);
+        }
+    }
+    return run_state;
+}
+
+// The ones below are not currently exported to Python.
+
+bool
+ThreadPlanPython::StopOthers ()
+{
+    // For now Python plans run all threads, but we should add some controls 
for this.
+    return false;
+}
+
+void
+ThreadPlanPython::GetDescription (Stream *s,
+                                lldb::DescriptionLevel level)
+{
+    s->Printf ("Python thread plan implemented by class %s.", 
m_class_name.c_str());
+}
+
+bool
+ThreadPlanPython::WillStop ()
+{
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
+    if (log)
+        log->Printf ("%s called on Python Thread Plan: %s )",
+                    __PRETTY_FUNCTION__, m_class_name.c_str());
+    return true;
+}

Modified: lldb/trunk/source/Target/ThreadPlanStepInRange.cpp
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlanStepInRange.cpp?rev=218642&r1=218641&r2=218642&view=diff
==============================================================================
--- lldb/trunk/source/Target/ThreadPlanStepInRange.cpp (original)
+++ lldb/trunk/source/Target/ThreadPlanStepInRange.cpp Mon Sep 29 18:17:18 2014
@@ -128,17 +128,31 @@ void
 ThreadPlanStepInRange::GetDescription (Stream *s, lldb::DescriptionLevel level)
 {
     if (level == lldb::eDescriptionLevelBrief)
+    {
         s->Printf("step in");
-    else
+        return;
+    }
+
+    s->Printf ("Stepping in");
+    bool printed_line_info = false;
+    if (m_addr_context.line_entry.IsValid())
+    {
+        s->Printf (" through line ");
+        m_addr_context.line_entry.DumpStopContext (s, false);
+        printed_line_info = true;
+    }
+
+    const char *step_into_target = m_step_into_target.AsCString();
+    if (step_into_target && step_into_target[0] != '\0')
+        s->Printf (" targeting %s", m_step_into_target.AsCString());
+
+    if (!printed_line_info || level == eDescriptionLevelVerbose)
     {
-        s->Printf ("Stepping through range (stepping into functions): ");
+        s->Printf (" using ranges:");
         DumpRanges(s);
-        const char *step_into_target = m_step_into_target.AsCString();
-        if (step_into_target && step_into_target[0] != '\0')
-            s->Printf (" targeting %s.", m_step_into_target.AsCString());
-        else
-            s->PutChar('.');
     }
+
+    s->PutChar('.');
 }
 
 bool
@@ -303,6 +317,7 @@ ThreadPlanStepInRange::ShouldStop (Event
     else
     {
         m_no_more_plans = false;
+        m_sub_plan_sp->SetPrivate(true);
         return false;
     }
 }

Modified: lldb/trunk/source/Target/ThreadPlanStepOut.cpp
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlanStepOut.cpp?rev=218642&r1=218641&r2=218642&view=diff
==============================================================================
--- lldb/trunk/source/Target/ThreadPlanStepOut.cpp (original)
+++ lldb/trunk/source/Target/ThreadPlanStepOut.cpp Mon Sep 29 18:17:18 2014
@@ -54,7 +54,6 @@ ThreadPlanStepOut::ThreadPlanStepOut
     m_return_addr (LLDB_INVALID_ADDRESS),
     m_stop_others (stop_others),
     m_immediate_step_from_function(NULL)
-
 {
     SetFlagsToDefault();
     SetupAvoidNoDebug(step_out_avoids_code_without_debug_info);
@@ -90,6 +89,7 @@ ThreadPlanStepOut::ThreadPlanStepOut
                                                             frame_idx - 1,
                                                             eLazyBoolNo));
             static_cast<ThreadPlanStepOut 
*>(m_step_out_to_inline_plan_sp.get())->SetShouldStopHereCallbacks(nullptr, 
nullptr);
+            m_step_out_to_inline_plan_sp->SetPrivate(true);
         }
         else
         {
@@ -177,10 +177,34 @@ ThreadPlanStepOut::GetDescription (Strea
         else if (m_step_through_inline_plan_sp)
             s->Printf ("Stepping out by stepping through inlined function.");
         else
-            s->Printf ("Stepping out from address 0x%" PRIx64 " to return 
address 0x%" PRIx64 " using breakpoint site %d",
-                       (uint64_t)m_step_from_insn,
-                       (uint64_t)m_return_addr,
-                       m_return_bp_id);
+        {
+            s->Printf ("Stepping out from ");
+            Address tmp_address;
+            if (tmp_address.SetLoadAddress (m_step_from_insn, &GetTarget()))
+            {
+                tmp_address.Dump(s, &GetThread(), 
Address::DumpStyleResolvedDescription, Address::DumpStyleLoadAddress);
+            }
+            else
+            {
+                s->Printf ("address 0x%" PRIx64 "", 
(uint64_t)m_step_from_insn);
+            }
+
+            // FIXME: find some useful way to present the m_return_id, since 
there may be multiple copies of the
+            // same function on the stack.
+
+            s->Printf ("returning to frame at ");
+            if (tmp_address.SetLoadAddress (m_return_addr, &GetTarget()))
+            {
+                tmp_address.Dump(s, &GetThread(), 
Address::DumpStyleResolvedDescription, Address::DumpStyleLoadAddress);
+            }
+            else
+            {
+                s->Printf ("address 0x%" PRIx64 "", (uint64_t)m_return_addr);
+            }
+
+            if (level == eDescriptionLevelVerbose)
+                s->Printf(" using breakpoint site %d", m_return_bp_id);
+        }
     }
 }
 
@@ -474,11 +498,16 @@ ThreadPlanStepOut::QueueInlinedStepPlan
                 inlined_sc.target_sp = GetTarget().shared_from_this();
                 RunMode run_mode = m_stop_others ? lldb::eOnlyThisThread : 
lldb::eAllThreads;
                 const LazyBool avoid_no_debug = eLazyBoolNo;
-                ThreadPlanStepOverRange *step_through_inline_plan_ptr = new 
ThreadPlanStepOverRange(m_thread, 
-                                                                               
                     inline_range, 
-                                                                               
                     inlined_sc, 
-                                                                               
                     run_mode,
-                                                                               
                     avoid_no_debug);
+
+                m_step_through_inline_plan_sp.reset (new 
ThreadPlanStepOverRange(m_thread, 
+                                                                               
  inline_range, 
+                                                                               
  inlined_sc, 
+                                                                               
  run_mode,
+                                                                               
  avoid_no_debug));
+                ThreadPlanStepOverRange *step_through_inline_plan_ptr
+                        = static_cast<ThreadPlanStepOverRange 
*>(m_step_through_inline_plan_sp.get());
+                m_step_through_inline_plan_sp->SetPrivate(true);
+                        
                 step_through_inline_plan_ptr->SetOkayToDiscard(true);          
                                                                          
                 StreamString errors;
                 if (!step_through_inline_plan_ptr->ValidatePlan(&errors))
@@ -493,7 +522,7 @@ ThreadPlanStepOut::QueueInlinedStepPlan
                     if (inlined_block->GetRangeAtIndex (i, inline_range))
                         step_through_inline_plan_ptr->AddRange (inline_range);
                 }
-                m_step_through_inline_plan_sp.reset 
(step_through_inline_plan_ptr);
+
                 if (queue_now)
                     m_thread.QueueThreadPlan (m_step_through_inline_plan_sp, 
false);
                 return true;

Modified: lldb/trunk/source/Target/ThreadPlanStepOverRange.cpp
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlanStepOverRange.cpp?rev=218642&r1=218641&r2=218642&view=diff
==============================================================================
--- lldb/trunk/source/Target/ThreadPlanStepOverRange.cpp (original)
+++ lldb/trunk/source/Target/ThreadPlanStepOverRange.cpp Mon Sep 29 18:17:18 
2014
@@ -62,12 +62,26 @@ void
 ThreadPlanStepOverRange::GetDescription (Stream *s, lldb::DescriptionLevel 
level)
 {
     if (level == lldb::eDescriptionLevelBrief)
+    {
         s->Printf("step over");
-    else
+        return;
+    }
+    s->Printf ("Stepping over");
+    bool printed_line_info = false;
+    if (m_addr_context.line_entry.IsValid())
+    {
+        s->Printf (" line ");
+        m_addr_context.line_entry.DumpStopContext (s, false);
+        printed_line_info = true;
+    }
+
+    if (!printed_line_info || level == eDescriptionLevelVerbose)
     {
-        s->Printf ("stepping through range (stepping over functions): ");
-        DumpRanges(s);    
+        s->Printf (" using ranges: ");
+        DumpRanges(s);
     }
+
+    s->PutChar('.');
 }
 
 void
@@ -317,11 +331,15 @@ ThreadPlanStepOverRange::ShouldStop (Eve
     {
         new_plan_sp = CheckShouldStopHereAndQueueStepOut (frame_order);
     }
-    
+
     if (!new_plan_sp)
         m_no_more_plans = true;
     else
+    {
+        // Any new plan will be an implementation plan, so mark it private:
+        new_plan_sp->SetPrivate(true);
         m_no_more_plans = false;
+    }
 
     if (!new_plan_sp)
     {

Modified: lldb/trunk/source/Target/ThreadPlanStepRange.cpp
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlanStepRange.cpp?rev=218642&r1=218641&r2=218642&view=diff
==============================================================================
--- lldb/trunk/source/Target/ThreadPlanStepRange.cpp (original)
+++ lldb/trunk/source/Target/ThreadPlanStepRange.cpp Mon Sep 29 18:17:18 2014
@@ -44,7 +44,8 @@ ThreadPlanStepRange::ThreadPlanStepRange
                                           Thread &thread, 
                                           const AddressRange &range, 
                                           const SymbolContext &addr_context, 
-                                          lldb::RunMode stop_others) :
+                                          lldb::RunMode stop_others,
+                                          bool given_ranges_only) :
     ThreadPlan (kind, name, thread, eVoteNoOpinion, eVoteNoOpinion),
     m_addr_context (addr_context),
     m_address_ranges (),
@@ -53,7 +54,8 @@ ThreadPlanStepRange::ThreadPlanStepRange
     m_parent_stack_id(),
     m_no_more_plans (false),
     m_first_run_event (true),
-    m_use_fast_step(false)
+    m_use_fast_step(false),
+    m_given_ranges_only (given_ranges_only)
 {
     m_use_fast_step = GetTarget().GetUseFastStepping();
     AddRange(range);
@@ -149,7 +151,7 @@ ThreadPlanStepRange::InRange ()
             break;
     }
     
-    if (!ret_value)
+    if (!ret_value && !m_given_ranges_only)
     {
         // See if we've just stepped to another part of the same line number...
         StackFrame *frame = m_thread.GetStackFrameAtIndex(0).get();


_______________________________________________
lldb-commits mailing list
lldb-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits

Reply via email to