//===-- 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 = nullptr); 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; ThreadPlanShouldStopHereCallbacks m_callbacks; void *m_baton; ThreadPlan *m_owner; lldb_private::Flags m_flags; private: DISALLOW_COPY_AND_ASSIGN(ThreadPlanShouldStopHere); }; } // namespace lldb_private #endif // liblldb_ThreadPlanShouldStopHere_h_