| //===-- ThreadPlanShouldStopHere.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_ThreadPlanShouldStopHere_h_ |
| #define liblldb_ThreadPlanShouldStopHere_h_ |
| |
| // C Includes |
| // C++ Includes |
| // Other libraries and framework includes |
| // Project includes |
| #include "lldb/Target/ThreadPlan.h" |
| |
| namespace lldb_private { |
| |
| // This is an interface that ThreadPlans can adopt to allow flexible modifications of the behavior |
| // when a thread plan comes to a place where it would ordinarily stop. If such modification makes |
| // sense for your plan, inherit from this class, and when you would be about to stop (in your ShouldStop |
| // method), call InvokeShouldStopHereCallback, passing in the frame comparison between where the step operation |
| // started and where you arrived. If it returns true, then QueueStepOutFromHere will queue the plan |
| // to execute instead of stopping. |
| // |
| // The classic example of the use of this is ThreadPlanStepInRange not stopping in frames that have |
| // no debug information. |
| // |
| // This class also defines a set of flags to control general aspects of this "ShouldStop" behavior. |
| // A class implementing this protocol needs to define a default set of flags, and can provide access to |
| // changing that default flag set if it wishes. |
| |
| class ThreadPlanShouldStopHere |
| { |
| public: |
| struct ThreadPlanShouldStopHereCallbacks |
| { |
| ThreadPlanShouldStopHereCallbacks() |
| { |
| should_stop_here_callback = nullptr; |
| step_from_here_callback = nullptr; |
| } |
| |
| ThreadPlanShouldStopHereCallbacks(ThreadPlanShouldStopHereCallback should_stop, |
| ThreadPlanStepFromHereCallback step_from_here) |
| { |
| should_stop_here_callback = should_stop; |
| step_from_here_callback = step_from_here; |
| } |
| |
| void |
| Clear() |
| { |
| should_stop_here_callback = nullptr; |
| step_from_here_callback = nullptr; |
| } |
| |
| ThreadPlanShouldStopHereCallback should_stop_here_callback; |
| ThreadPlanStepFromHereCallback step_from_here_callback; |
| }; |
| |
| enum |
| { |
| eNone = 0, |
| eAvoidInlines = (1 << 0), |
| eStepInAvoidNoDebug = (1 << 1), |
| eStepOutAvoidNoDebug = (1 << 2) |
| }; |
| |
| //------------------------------------------------------------------ |
| // Constructors and Destructors |
| //------------------------------------------------------------------ |
| ThreadPlanShouldStopHere (ThreadPlan *owner); |
| |
| ThreadPlanShouldStopHere (ThreadPlan *owner, |
| const ThreadPlanShouldStopHereCallbacks *callbacks, |
| void *baton = NULL); |
| virtual |
| ~ThreadPlanShouldStopHere(); |
| |
| // Set the ShouldStopHere callbacks. Pass in null to clear them and have no special behavior (though you |
| // can also call ClearShouldStopHereCallbacks for that purpose. If you pass in a valid pointer, it will |
| // adopt the non-null fields, and any null fields will be set to the default values. |
| |
| void |
| SetShouldStopHereCallbacks (const ThreadPlanShouldStopHereCallbacks *callbacks, void *baton) |
| { |
| if (callbacks) |
| { |
| m_callbacks = *callbacks; |
| if (!m_callbacks.should_stop_here_callback) |
| m_callbacks.should_stop_here_callback = ThreadPlanShouldStopHere::DefaultShouldStopHereCallback; |
| if (!m_callbacks.step_from_here_callback) |
| m_callbacks.step_from_here_callback = ThreadPlanShouldStopHere::DefaultStepFromHereCallback; |
| } |
| else |
| { |
| ClearShouldStopHereCallbacks (); |
| } |
| m_baton = baton; |
| } |
| |
| void |
| ClearShouldStopHereCallbacks() |
| { |
| m_callbacks.Clear(); |
| } |
| |
| bool |
| InvokeShouldStopHereCallback (lldb::FrameComparison operation); |
| |
| lldb::ThreadPlanSP |
| CheckShouldStopHereAndQueueStepOut (lldb::FrameComparison operation); |
| |
| lldb_private::Flags & |
| GetFlags () |
| { |
| return m_flags; |
| } |
| |
| const lldb_private::Flags & |
| GetFlags () const |
| { |
| return m_flags; |
| } |
| |
| protected: |
| static bool |
| DefaultShouldStopHereCallback (ThreadPlan *current_plan, Flags &flags, lldb::FrameComparison operation, void *baton); |
| |
| static lldb::ThreadPlanSP |
| DefaultStepFromHereCallback (ThreadPlan *current_plan, Flags &flags, lldb::FrameComparison operation, void *baton); |
| |
| virtual lldb::ThreadPlanSP |
| QueueStepOutFromHerePlan (Flags &flags, lldb::FrameComparison operation); |
| |
| // Implement this, and call it in the plan's constructor to set the default flags. |
| virtual void SetFlagsToDefault () = 0; |
| |
| //------------------------------------------------------------------ |
| // Classes that inherit from ThreadPlanShouldStopHere can see and modify these |
| //------------------------------------------------------------------ |
| ThreadPlanShouldStopHereCallbacks m_callbacks; |
| void * m_baton; |
| ThreadPlan *m_owner; |
| lldb_private::Flags m_flags; |
| |
| private: |
| //------------------------------------------------------------------ |
| // For ThreadPlanShouldStopHere only |
| //------------------------------------------------------------------ |
| |
| DISALLOW_COPY_AND_ASSIGN (ThreadPlanShouldStopHere); |
| |
| }; |
| |
| } // namespace lldb_private |
| |
| #endif // liblldb_ThreadPlanShouldStopHere_h_ |